此页面指导具有 Unity UI(用户界面) 允许用户与您的应用程序交互。Unity 目前支持三种 UI 系统。 更多信息
查看 词汇表 (uGUI) 经验的开发者过渡到新的 UI Toolkit 系统。它探讨了 uGUI 和 UI Toolkit 之间的异同。
由于 uGUI 是一种仅限运行时的 UI 系统,因此此页面重点关注运行时 UI。UI Toolkit 可以创建运行时和编辑器 UI。本指南适用于 UI Toolkit 的两种用例。
uGUI 和 UI Toolkit 都在层次结构树中构建和维护 UI。在 uGUI 中,此层次结构中的所有元素在层次结构视图面板中显示为单个 游戏对象Unity 场景中的基本对象,可以表示角色、道具、场景、摄像机、航路点等。游戏对象的函数由附加到它的组件定义。 更多信息
查看 词汇表。在 UI Toolkit 中,视觉元素视觉树中的一个节点,它实例化或派生自 C# VisualElement
类。您可以设置外观、定义行为,并将其作为 UI 的一部分显示在屏幕上。 更多信息
查看 词汇表 被组织成一个 视觉树由轻量级节点组成的对象图,它包含窗口或面板中的所有元素。它定义了您使用 UI Toolkit 构建的每个 UI。
查看 词汇表。该 视觉树 在面板中不可见。
要查看和调试 UI Toolkit 中的 UI 层次结构,您可以使用 UI 调试器。您可以在编辑器工具栏中找到 UI 调试器,位于 窗口 > UI Toolkit > 调试器。
uGUI 中的 Canvas
组件类似于 UI Toolkit 中的 UIDocument
组件。两者都是附加到游戏对象的 MonoBehaviour。
在 uGUI 中,Canvas
组件位于 UI 树的根部。它与 Canvas Scaler
组件一起工作以确定下方 UI 的排序顺序、渲染和缩放模式。
在 UI Toolkit 中,UIDocument
组件包含对 PanelSettings
对象的引用。PanelSettings
包含 UI 的渲染设置,包括缩放模式和排序顺序。多个 UIDocument
组件可以指向同一个 PanelSettings
对象,这在同一个 场景场景包含游戏环境和菜单。将每个唯一的场景文件视为一个独特关卡。在每个场景中,您放置环境、障碍物和装饰,本质上是在分块设计和构建您的游戏。 更多信息
查看 词汇表 中使用多个 UI 屏幕时会优化性能。
在 uGUI 中,UI 树层次结构位于包含 Canvas
组件的游戏对象下方。在 UI Toolkit 中,UIDocument
组件包含对视觉树的根元素的引用。
UIDocument
组件还包含对 UXML 文件的引用,该文件定义了在运行时构建视觉树的 UI 布局。有关更多信息,请参阅 创建 UI 部分。
注意:对于编辑器 UI,不需要 UIDocument
组件。您可以从 EditorWindow
派生自定义类,然后实现 CreateGUI()
。有关实际示例,请参阅有关 创建自定义编辑器窗口 的指南。
UI Toolkit 将 UI 元素称为控件或视觉元素。UI 元素的示例包括
uGUI 从游戏对象构建 UI 层次结构。添加新的 UI 元素需要向层次结构添加新的游戏对象。单个控件以 MonoBehaviour
组件的形式实现。
在 UI Toolkit 中,视觉树 是虚拟的,不使用游戏对象。您不能再在层次结构视图中构建或查看 UI 层次结构,但这消除了为每个 UI 元素使用游戏对象的开销。
在 uGUI 中,UI 元素派生(直接或间接地)自 UIBehavior
基类。类似地,在 UI Toolkit 中,所有 UI 元素都派生自名为 VisualElement
的基类。关键区别在于 VisualElement
类没有从 MonoBehaviour
派生。您不能将视觉元素附加到游戏对象。
在脚本中使用 UI Toolkit 控件类似于使用 uGUI 控件。
下表显示了 uGUI 中对 UI 控件的常见脚本交互及其 UI Toolkit 对应项。
操作 | uGUI | UI Toolkit |
---|---|---|
将文本写入标签 | m_Label.text = "我的文本"; |
m_Label.text = "我的文本"; |
读取切换状态 | bool isToggleChecked = m_Toggle.isOn; |
bool isToggleChecked = m_Toggle.value; |
向按钮分配回调 | m_Button.onClick.AddListener(MyCallbackFunc); |
m_Button.clicked += MyCallbackFunc_1; 或 m_Button.RegisterCallback<ClickEvent>(MyCallbackFunc_2);
|
要了解有关控件及其属性和事件的更多信息,请参阅 控件概述 页面。
在 uGUI 中,脚本一段代码,允许您创建自己的组件,触发游戏事件,随着时间的推移修改组件属性,并以任何您喜欢的方式响应用户输入。 更多信息
查看 词汇表 可以通过两种方式访问 UI 元素
GetComponentInChildren<T>()
)在层次结构中查找组件。由于 UI Toolkit 中没有游戏对象或组件,因此您不能直接在编辑器中为控件分配引用。必须使用查询函数在运行时解析它们。相反,通过 UIDocument
组件访问视觉树。
UIDocument
是一个 MonoBehaviour
,因此您可以将其分配为引用并使其成为 预制件一种资产类型,允许您存储包含组件和属性的游戏对象。预制件充当模板,您可以从该模板在场景中创建新的对象实例。 更多信息
查看 词汇表 的一部分。UIDocument
组件包含对根视觉元素的引用。从根部开始,脚本可以通过类型或名称查找子元素,类似于 uGUI。
下表显示了在 Unity UI 和 UI Toolkit 中访问 UI 控件的直接比较
操作 | uGUI | UI Toolkit |
---|---|---|
按名称查找 UI 元素 | transform.FindChild("childName"); |
rootVisualElement.Query("childName"); |
按类型查找 UI 元素 | transform.GetComponentInChildren<Button>(); |
rootVisualElement.Query<Button>(); |
在编辑器中直接分配引用 | 可能 | 不可能 |
uGUI 和 UI Toolkit 之间最大的区别之一是用户界面的创建。
uGUI 和 UI Toolkit 都允许您直观地构建 UI 并预览编辑器中的 UI。在 uGUI 中,UI 然后与附加到单个 UI 控件的任何逻辑脚本一起保存在预制件中。
在 UI Toolkit 中,UI 布局是在 UI Builder 中创建的,然后保存为一个或多个 UXML 文件。在运行时,UIDocument
组件加载视觉树在内存中组装的 UXML 文件。
对于类似于 uGUI 的方法,您可以直接从脚本创建 UI 控件,然后在运行时将它们添加到视觉树中。
uGUI 使用游戏对象来表示单个 UI 控件和包含视觉效果和逻辑的预制件。UI Toolkit 采取了不同的可重用性方法,因为它将逻辑和布局分开。您可以通过 UXML 和自定义控件创建可重用的 UI 组件。
要在 UI Toolkit 中创建类似于预制件的模板
UIDocument
组件的游戏对象。在 uGUI 中,在屏幕上排列单个 UI 元素是一个手动过程。默认情况下,UI 控件是自由浮动的,只受其直接父元素的影响。同一父元素下的其他 UI 控件不会影响其兄弟元素的位置或大小。枢轴点和锚点控制元素的位置和大小。
UI Toolkit 布局系统受到网页设计的启发,基于自动布局生成。自动布局系统默认影响所有元素,元素的大小和位置会影响同一父元素下的其他元素。
UI Toolkit 中的默认行为类似于将所有元素放置在 uGUI 中的 VerticalLayoutGroup
中,并将 LayoutElement
组件添加到每个元素中。
您可以通过更改视觉元素的 IStyle position
属性来禁用自动布局生成。所有视觉元素都具有此属性。有关代码示例,请参阅 视觉树。
UI Toolkit 没有直接等效于 UI 元素的锚点和枢轴点,因为其基本布局与 uGUI 相比存在差异。
元素的大小和位置由布局引擎控制。有关更多信息,请参阅 布局引擎 和 坐标和位置系统。
在 uGUI 中,游戏对象在层次结构中的顺序决定了渲染顺序。层次结构中较低的对象最后渲染,并出现在顶部。在一个包含多个画布的场景中,根 Canvas
组件上的 排序顺序
决定了单个 UI 树的渲染顺序。
UI Toolkit 中的 视觉树 中的渲染顺序与之相同。父元素在子元素之前渲染,子元素从第一个到最后一个渲染,以便最后一个出现在顶部。在一个包含多个 UI 文档的场景中,渲染顺序由根 UIDocument
组件上的 排序顺序
设置决定。
要更改 uGUI 中元素的渲染顺序(例如,使元素出现在最上面),您可以调用游戏对象 Transform
组件上的兄弟元素函数。VisualElement
类提供可比较的函数来控制渲染顺序。由于所有 UI Toolkit 控件都派生自此类,因此所有控件都可以访问此函数。
下表显示了 uGUI 中用于控制渲染顺序的函数以及 UI Toolkit 中的等效函数
操作 | uGUI | UI Toolkit |
---|---|---|
使元素在所有其他兄弟元素下方渲染 | transform.SetAsFirstSibling(); |
myVisualElement.SendToBack(); |
使元素在所有其他兄弟元素之上渲染 | transform.SetAsLastSibling(); |
myVisualElement.BringToFront(); |
手动控制元素相对于其兄弟元素的渲染顺序 | transform.SetSiblingIndex(newIndex); |
myVisualElement.PlaceBehind(sibling); myVisualElement.PlaceInFront(sibling);
|
就像在 uGUI 中一样,UI 工具包中的用户交互会触发事件。代码可以订阅以接收事件的回调,例如按下按钮或移动滑块。
在 uGUI 中,所有 UI 元素都基于 MonoBehaviour,并且可以在编辑器中公开其事件。这允许使用其他游戏对象设置逻辑,例如隐藏或显示其他 UI 元素,或分配回调函数。
在 UI 工具包中,逻辑和 UI 布局是分开存储的。回调不再可以直接在游戏对象上设置或存储在预制件中。您必须在运行时设置所有回调,并通过脚本处理它们。
Button playButton = new Button("Play");
playButton.RegisterCallback<ClickEvent>(OnPlayButtonPressed);
...
private void OnPlayButtonPressed(ClickEvent evt)
{
// Handle button press
}
UI 工具包中的事件分发系统与 uGUI 中的事件不同。根据事件类型,事件不仅发送到目标 UI 控件,还发送到所有父控件。
要了解更多信息,请参阅 分发事件。
您可以在同一个项目中使用 uGUI 和 UI 工具包。
在其当前版本中,UI 工具包不支持 3D 世界空间拾取和渲染。您应该使用 UI 工具包制作整个游戏菜单,并使用 uGUI 制作您的 3D 世界空间。
您也可以使用 uGUI 制作整个项目,只用 UI 工具包制作一些菜单项。
对于任何不在其自身边界之外进行交互的项目,您可以使用 UI 工具包或 uGUI。例如,对于运行时 UI,您可以使用 uGUI 创建屏幕上的按钮,例如移动设备的操纵杆,并使用 UI 工具包创建模态窗口。
但是,混合 UI 之间的复杂交互不起作用
RenderTexture
进行绘制,但事件不会赶上。