进度条通常用于让玩家知道某事正在发生(例如游戏加载)或让他们知道某事需要多长时间。 在本教程中,您将学习一些使用 UI Toolkit 和 DOTween 创建和动画进度条的技术。
学习成果预览
UI Toolkit不能做遮罩,也不能直接使用动画系统。通过本文的学习,你将会攻克这两个技术难点。最终你将会掌握以下几点:
1. 使用 UI Builder 工具设计 UI。
2. 向您的游戏添加运行时 UI。
3. 通过 DOTween 为 UI 设置动画。
前置条件
1. Unity 2020.3.0f1 (LTS) 以上的版本,本例使用的是2021.1.16f1c1。
2. 有一定的C#编程能力,了解如何在代码中控制Unity组件。
参考文档
Unity Manual: UI Toolkit
Unity Manual: UI Event System
Unity Manual: UI Builder
DOTween Documentation
1. 准备工作
UI Toolkit是unity提供的一个新的UI系统,与UGUI是独立存在的,二者没有直接关系。项目中可以单独使用UI Tookit,也可以和UGUI一起使用。
安装UI Toolkit运行时和UI Builder
Unity2021.1之前的版本需要单独安装UI Builder。在Package Manager中启用预览(Enalble Preview Packages),搜索UI Builder然后安装即可。
安装Dotween
1.在浏览器中打开Unity Asset Store页面 ,定位到Dotween。
2.点击添加至我的资源。
3.在Unity中打开Package Manager,将Package过滤器设置为My Asset。
4.找到Dotween(HOTween v2)点击安装。
2. UI Toolkit以及UI Builder基础
UI Toolkit
UI Toolkit完全改变了创建运行时游戏UI的模式,跟UGUI中的Canvas与Gameobject方式完全说拜拜了,取而代之的是更接近Web设计UI的模式,也会使用类似于CSS的样式表。所有的组件都是可以复用的,让设计模式变得更快了。新的UI系统中有两个重要的概念:
1. UXML——Unity extensibale Markup Language Documents:定义UI界面以及可复用的UI模板结构。
2. USS——Unity Style Sheets:类似于Web中的CSS,你可以通过USS设置UI的样式和行为。
在学习和使用UI Toolkit的时候,我们会用到以下的工具:
1. UI Builder:可视化的UXML和USS编辑器。可以通过Window>UI Toolkit>UI Builder来打开。
2. UI Debugger:UI调试工具,可以查看UI层级以及样式结构等重要信息。可以通过Window>UI Toolkit>UI Debugger来打开。
3. UI Samples:包含了很多UI控件的代码范例。可以通过Window>UI Toolkit>Samples来打开。
UI Builder
UI Builder可以可视化创建和编辑UXML和USS文件,同时也支持使用代码创建和管理UI样式。UI Builder窗口分为6大模块。
1. StyleSheets:管理本文档中使用的样式表和单个选择器。样式表可以跨多个文档共享,从而最大化重用性。
2. Hierarchy:文档中所有元素的列表。
3. Library:包含可以实例化的标准元素的列表。标准选项卡包含Unity的UI文档。Project选项卡包含在项目中创建的UI文档。
4. ViewPort:UI文档的可视化界面。
5. Inspector:包含当前在层次结构或样式表部分中选择的元素的可修改属性和样式属性。
6. Code Preview:显示UI Builder根据你的设计生成的UXML和USS代码。
设计任务——加载进度条
我们先创建第一个进度条。本例中创建的进度条完全使用UI Toolkit中的基本元素,也就是说不会用到任何的图片素材。
在UI Builder中点击Hierarchy窗口中的第一个项目“unsaved window.uxml”。右侧Inspector会显示基本的属性。将width设置为360,height设置为130。
从Library中拖拽VisualElement组件,放到Hierarchy窗口,点击这个醉组件打开看到右侧的属性。设置如下:
Name: Container
Size>Width: 350 px
再拖一个VisualElement到hierarchy窗口中,成为Container的子节点。在右侧的属性中设置如下:
Name: Container_Header
Flex>Direction: row
Text>Font: Recursive
Text >Size: 25px.
拖拽一个Label控件作为Container_Header的一个子节点。设置属性如下:
Name: txt_Loading
Text: LOADING….
Flex>Grow: 1
Font Style: Bold
Text>Color: # 00E6FF
拖拽一个Label控件作为Container_Header的最后一个子节点。设置属性如下:
Name: txt_Percentage
Text: 0%
Font Style: Italic
Text>Color: # 00E6FF
再拖一个VisualElement作为Container的最后一个子节点。属性如下:
Name: Container_Bar
Size>Height: 75px
Border>Color: # 00E6FF
Border>Width: 3px
再拖一个VisualElement作为Container_Bar的最后一个子节点。属性如下:
Name: bar_Progress
Size>Height: 100%
Size>Width: 0%
Margin & Padding>Margin: 10px
Background>Color: # 00E6FF
在窗口区域的上部点击File>Save As来保存UXML文档,命名为Progressbar_Straight_Border。 你将会看到如下图所示的界面:
设计任务——将UI加入到游戏界面中
在将UI添加到游戏中之前,我们需要创建一个全屏的UI容器,在UI Builder中点击File>New,点击.uxml文件在属性窗口中开启Match Game View。这个属性可以自动设置UI的宽和高来适应Game窗口。
下一步将progress bar加入到视图中间。在Library分区中点击Project切页选项卡,找到Progressbar_Straight_Border.uxml。将他拖拽到Hierarchy窗口中,设置属性如下:
Flex>Grow: 1
Align>Align Items: center
Align>Justify Content: center
将文件保存命名为LoadScreen。
在场景中显示进度条
UI Toolkit带来了一个新的组件叫做UI Document,通过这个组件才能够显示UI元素。在新的场景中选择GameObject > UI Toolkit > UI Document。重命名为ProgressBar。
在你的场景中可以看到这个带有UI Document组建的游戏物体,这个组件有三个属性:
Panel Settings:面板是所有UI文档都附加到的根VisualElement。它是在运行时处理在场景中绘制UI的工具。面板设置文件具有各种属性,您可以设置这些属性以影响运行时。
Source Asset:对应与面板关联的 UXML 文件的引用(根 VIsualElement)。可以有多个。
Sort Order: 指定此 UI 文档相对于属于同一 PanelSettings 或 UI 文档父级的其他 UI 文档的显示顺序。
只有一个属性要改变。 将Source Asset设置为 LoadScreen。 按下播放键,现在应该会在游戏窗口底部看到一个静态进度条。
设计任务——让进度条动起来
这里使用了DOTween中的动画系统来实现的动画效果。创建脚本名为LoadingProgressBarAnimation。
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using DG.Tweening;
using UnityEngine.UIElements;
public class LoadingProgressBarAnimation : MonoBehaviour
{
private VisualElement m_Root;
private VisualElement m_LoadingProgressBar;
private Label m_LoadingPercentageText;
void Start()
{
//Grab a reference to the root element that is drawn
m_Root = GetComponent
().rootVisualElement; //Search the root for the two dynamic elements that need to be animated
m_LoadingProgressBar = m_Root.Q
("bar_Progress"); m_LoadingPercentageText = m_Root.Q
Invoke("AnimateLoadingBar", 2);
}
private void AnimateLoadingBar()
{
//Grab the final width of the progress bar based on the parent and
//remove 25px to account for margins
float endWidth = m_LoadingProgressBar.parent.worldBound.width - 25;
DOTween.To(() => 5, x => m_LoadingPercentageText.text = $"{x}%",
100, 5f).SetEase(Ease.Linear);
DOTween.To(() => m_LoadingProgressBar.worldBound.width, x =>
m_LoadingProgressBar.style.width = x, endWidth, 5f).SetEase(Ease.Linear);
}
}
将代码附在ProgressBar物体上,点击播放按钮。不出意外的话你可以看到如下图所示的进度条动画。