版本:Unity 6 (6000.0)
语言:英语
从 Unity UI (uGUI) 迁移到 UI 工具包
Unity UI

从即时模式 GUI (IMGUI) 迁移到 UI 工具包

本指南面向的是了解 即时模式 GUI (IMGUI) 的开发者,以便他们迁移到 UI(用户界面)允许用户与您的应用程序进行交互。Unity 目前支持三个 UI 系统。了解更多信息
请参阅 词汇表
工具包。本指南重点介绍编辑器 UI,但其信息也同样适用于运行时 UI。

主要区别

代码驱动与 UI 驱动

IMGUI 是通过实现此功能的 C# 脚本中对 OnGUI 函数的调用进行代码驱动的。UI 工具包为编辑器 UI 创建提供了更多选项。使用 UI 工具包,您可以在 C# 脚本一段可让您创建自己的组件、触发游戏事件、随着时间的推移修改组件属性并以任何您喜欢的方式响应用户输入的代码。了解更多信息
请参阅 词汇表
中定义行为。然而,在定义 UI 元素和样式时,除了 C#,您还可以在 UI 生成器 中以可视方式定义 UI 控件,或直接用 XML 类似的文本文件(称为 UXML) 编写。有关更多信息,请参阅 开始使用 UI 工具包

直接模式与保留模式

使用 IMGUI 时,您可以在使用 OnGUI() 函数重新绘制 UI 时描述 UI 树形结构。必须在事件进入 UI 时或重新绘制 UI 时调用此函数。对于不同事件之间的 UI 树形结构,没有任何持久性信息。而您则使用 UI Toolkit 在名为 可视化树对象图,由轻量级节点构成,其中包含窗口或面板中的所有元素。它定义了使用 UI Toolkit 构建的所有 UI。
请参阅 词汇表
的树形结构中创建 可视元素可视化树节点,实例化或源于 C# VisualElement 类。您可以设置外观样式、定义行为以及将其显示在屏幕上作为 UI 的一部分。 更多信息
请参阅 词汇表

常量与状态更改

IMGUI 基于 OnGUI() 函数,此函数至少每帧运行一次。为每一帧定义 UI 的外观和行为。OnGUI()` 的正文可能包含许多条件和不同状态。

UI Toolkit 在事件驱动系统中运行。您可以定义 UI 在其默认状态下的外观,并在事件响应中定义 UI 的行为。在 UI Toolkit 中做出的任何更改都会对 UI 的状态造成持久更改。

例如,IMGUI 中按钮的声明形式如下

if (GUILayout.Button("Click me!"))
{
    //Code runs here in frames where the user clicks the button.

    //Code makes changes to the UI for frames where the user has just clicked the button.
}
else
{
    //Code specifies what happens in all other frames.
}

上面的示例在 UI Toolkit 中形式如下

UIDocument document = GetComponent<UIDocument>();

//Create button.
Button button = new Button();
button.text = "Click me!";

//Set up event handler.
button.RegisterCallback<ClickEvent>((ClickEvent evt) =>
{
    //Code runs here after button receives ClickEvent.
});

//Add button to UI.
document.rootVisualElement.Add(button);

有关如何使用 UI Toolkit 创建自定义编辑器窗口的完整示例,请参阅 使用 UI Toolkit 入门

IMGUI 支持

使用 IMGUIContainer 将 IMGUI 代码放在 VisualElement 内。OnGUI() 中能做的一切都得到支持。

您可以排列多个 IMGUIContainer 并通过混合使用 GUILayout 和 UI Toolkit 布局对其进行布局。请注意,不可能在 IMGUIContainer 中添加 VisualElement 实例。

IMGUIContainer example
IMGUIContainer 示例

从 IMGUI 到 UI Toolkit 转换

下表列出了 IMGUI 与 UI Toolkit 之间的等效函数

操作 IMGUI UI 工具包
创建 编辑器窗口 EditorWindow.OnGUI() EditorWindow.CreateGUI()
创建 属性抽屉通过使用脚本上的属性来定制检查器窗口中某些控件外观的 Unity 功能,或通过控制特定可序列化类的外观 了解更多信息
请参阅 词汇表
或属性属性
PropertyDrawer.OnGUI() PropertyDrawer.CreatePropertyGUI()
检查器显示有关当前选定游戏对象、资产或项目设置的信息的 Unity 窗口,让你可以检查和编辑值。 了解更多信息
请参阅 词汇表
创建自定义编辑器
Editor.OnInspectorGUI() Editor.CreateInspectorGUI()

下表列出了 IMGUI 和 UI Toolkit 之间等效的方法、类和属性

IMGUI IMGUI 命名空间 UI 工具包
AddCursorRect() EditorGUIUtility 设置 VisualElement.style.cursor,或在 UI Builder 或 USS 中设置视觉元素的光标纹理。如需更详细的交互性,请使用 C# 事件。
AreaScope GUILayout 在 UI Toolkit 中通常不需要作用域。请参阅 BeginArea()
BeginArea() GUILayout 要定义区域本身,请创建一个视觉元素,并设置 style.positionPosition.Absolute。如需为该区域创建子项,请在其下方创建子视觉元素。
BeginBuildTargetSelectionGrouping() EditorGUILayout 无等效项。
BeginChangeCheck() EditorGUI 在更改检查范围中的每个元素上注册回调。如果将 PropertyField 用作自定义检查器中序列化字段的替身,请使用 PropertyField.RegisterCallback<SerializedPropertyChangeEvent>()PropertyField.RegisterValueChangeCallback()。在所有其他情况下,请使用 VisualElement.RegisterCallback<ChangeEvent<T>>()VisualElement.RegisterValueChangedCallback<T>()
BeginDisabledGroup() EditorGUI VisualElement.SetEnabled(false)
BeginFoldoutHeaderGroup() EditorGUI、EditorGUILayout 请参阅 Foldout()
BeginGroup() GUI 请参阅 BeginArea()
BeginHorizontal() EditorGUILayout、GUILayout 请参阅 BeginArea()
BeginProperty() EditorGUI 如果你使用 BeginProperty()/EndProperty() 将一个简单控件绑定到序列化属性,你可以通过调用 BindProperty(),通过设置 bindingPath 或通过设置 binding-path UXML 属性来在 UI Toolkit 中执行此操作。如果你使用 BeginProperty()/EndProperty() 使复杂自定义 UI 成为单一属性,则在 UI Toolkit 中不支持该操作。
BeginScrollView() EditorGUILayout、GUI、GUILayout UnityEngine.UIElements.ScrollView
BeginToggleGroup() EditorGUILayout 无等效项。
BeginVertical() EditorGUILayout、GUILayout 请参阅 BeginArea()
BoundsField() EditorGUI、EditorGUILayout BoundsField
BoundsIntField() EditorGUI、EditorGUILayout BoundsIntField
Box() GUI, GUILayout Box
BringWindowToBack() GUI 请参阅 Window()
BringWindowToFront() GUI 请参阅 Window()
Button() GUI, GUILayout Button
CanCacheInspectorGUI() EditorGUI 在保留模式中不需要。
ChangeCheckScope EditorGUI 在 UI Toolkit 中通常不需要范围。请参阅 BeginChangeCheck()
ColorField() EditorGUI、EditorGUILayout ColorField
CommandEvent() EditorGUIUtility 在保留模式中通常不需要。使用 C# 回调来处理事件。
CurveField() EditorGUI、EditorGUILayout CurveField
DelayedDoubleField() EditorGUI、EditorGUILayout DoubleField,其中 isDelayed 设置为 true
DelayedFloatField() EditorGUI、EditorGUILayout FloatField,其中 isDelayed 设置为 true
DelayedIntField() EditorGUI、EditorGUILayout IntegerField,其中 isDelayed 设置为 true
DelayedTextField() EditorGUI、EditorGUILayout TextField,其中 isDelayed 设置为 true
DisabledScope EditorGUI 在 UI Toolkit 中通常不需要范围。请参阅 BeginDisabledGroup()
DoubleField() EditorGUI、EditorGUILayout DoubleField
DragWindow() GUI 请参阅 Window()
DrawPreviewTexture() EditorGUI 无等效项。
DrawRect() EditorGUI 使用 VisualElement。将 style.position 设置为 Absolute。设置 style.topstyle.left 来定义位置。设置 style.widthstyle.height 来定义大小。设置 style.backgroundColor 来设置颜色。
DrawTexture() GUI Image。将 tintColor 代替 color。没有 false alphaBlend 的等价项。没有 borderWidthborderWidthsborderRadiusborderRadiuses 的等价项。
DrawTextureAlpha() EditorGUI 无等效项。
DrawTextureWithTexCoords() GUI Image。将 uv 代替 texCoords。没有 false alphaBlend 的等价项。
DropdownButton() EditorGUI、EditorGUILayout 没有完全等价的项。使用成熟的 DropdownField,而不只是使用 DropdownButton()
DropShadowLabel() EditorGUI Label,其中在 style.textShadow 中设置了阴影值。
EditorToolbar() EditorGUILayout 使用 Toolbar 编写一个 ToolManager,每个工具创建一个 ToolbarButton。对于每个 ToolbarButton,注册一个回调函数,已在点击时调用 ToolManager.SetActiveTool()ToolManager.RestorePreviousTool() 以使此按钮激活工具或撤销激活工具。
EndArea() GUILayout 请参阅 BeginArea()
EndBuildTargetSelectionGrouping() EditorGUILayout BeginBuildTargetSelectionGrouping()
EndChangeCheck() EditorGUI BeginChangeCheck()
EndDisabledGroup() EditorGUI BeginDisabledGroup()
EndFoldoutHeaderGroup() EditorGUI、EditorGUILayout 请参阅 Foldout()
EndGroup() GUI 请参阅 BeginArea()
EndHorizontal() EditorGUILayout、GUILayout 请参阅 BeginArea()
EndProperty() EditorGUI BeginProperty()
EndScrollView() EditorGUILayout、GUI、GUILayout BeginScrollView()
EndToggleGroup() EditorGUILayout BeginToggleGroup()
EndVertical() EditorGUILayout、GUILayout 请参阅 BeginArea()
EnumFlagsField() EditorGUI、EditorGUILayout EnumFlagsField
EnumPopup() EditorGUI、EditorGUILayout EnumField
ExpandHeight() GUILayout 无等效项。
ExpandWidth() GUILayout 无等效项。
FlexibleSpace() GUILayout Space()
FloatField() EditorGUI、EditorGUILayout FloatField
FocusControl() GUI VisualElement.Focus()
FocusTextInControl() EditorGUI TextField.Focus()
FocusWindow() GUI 请参阅 Window()
Foldout() EditorGUI、EditorGUILayout Foldout
GetControlRect() EditorGUILayout 仅在从 EditorGUILayout 转换为 EditorGUI 时需要。UI Toolkit 中不需要。
GetNameOfFocusedControl() GUI VisualElement.focusController.focusedElement
GetPropertyHeight() EditorGUI PropertyField.layout.height
GradientField() EditorGUI、EditorGUILayout GradientField
GroupScope GUI 在 UI Toolkit 中通常不需要作用域。请参阅 BeginArea()
Height() GUILayout VisualElement.style.height
HelpBox() EditorGUI、EditorGUILayout HelpBox
HorizontalScope EditorGUILayout、GUILayout 在 UI Toolkit 中通常不需要作用域。请参阅 BeginArea()
HorizontalScrollbar() GUI, GUILayout Scrollerdirection 设置为 Horizontal
HorizontalSlider() GUI, GUILayout Sliderdirection 设置为 Horizontal
InspectorTitlebar() EditorGUI、EditorGUILayout 无等效项。
IntField() EditorGUI、EditorGUILayout IntegerField
IntPopup() EditorGUI、EditorGUILayout 无等效项。
IntSlider() EditorGUI、EditorGUILayout SliderInt
Label() GUI, GUILayout Label
LabelField() EditorGUI、EditorGUILayout TextFieldisReadOnly 设置为 true。
LayerField() EditorGUI、EditorGUILayout LayerField
LinkButton() EditorGUI、EditorGUILayout 无等效项。
Load() EditorGUIUtility 使用 C# 时,可以按原样使用此函数并将其返回值指定给所需的 VisualElement.style 属性。使用 USS 时,将函数 resource() 与提供给 Load() 的相同参数配合使用。
LongField() EditorGUI、EditorGUILayout LongField
MaskField() EditorGUI、EditorGUILayout MaskField
MaxHeight() GUILayout VisualElement.style.maxHeight
MaxWidth() GUILayout VisualElement.style.maxWidth
MinHeight() GUILayout VisualElement.style.minHeight
MinMaxSlider() EditorGUI、EditorGUILayout MinMaxSlider
MinWidth() GUILayout VisualElement.style.minWidth
ModalWindow() GUI 请参阅 Window()
[NonReorderable] 属性 确保 ListView.reorderable 为 false。
ObjectField() EditorGUI、EditorGUILayout ObjectField
PasswordField() EditorGUI、EditorGUILayout、GUI、GUILayout TextField,其中 isPasswordField 设置为 true
PixelsToPoints() EditorGUIUtility 适用于 UI 工具包。
PointsToPixels() EditorGUIUtility 适用于 UI 工具包。
Popup() EditorGUI、EditorGUILayout PopupField<T0>
ProgressBar() EditorGUI ProgressBar
PropertyField() EditorGUI、EditorGUILayout PropertyField
PropertyScope EditorGUI UI 工具包中通常不需要范围。参见 BeginProperty()
RectField() EditorGUI、EditorGUILayout RectField
RectIntField() EditorGUI、EditorGUILayout RectIntField
RepeatButton() GUI, GUILayout RepeatButton
ScrollTo() GUI ScrollView.ScrollTo()ScrollView.scrollOffset
ScrollViewScope EditorGUILayout、GUI、GUILayout UI 工具包中通常不需要范围。参见 BeginScrollView()
SelectableLabel() EditorGUI、EditorGUILayout Label,其中 isSelectablefocusable 设置为 true。
SelectionGrid() GUI, GUILayout RadioButton
SetNextControlName() GUI VisualElement.name
singleLineHeight EditorGUIUtility 使用 USS 变量 --unity-metrics-single_line-height
Slider() EditorGUI、EditorGUILayout Slider
Space() EditorGUILayout、GUILayout 使用 flex 属性配置视觉元素之间的间距。
TagField() EditorGUI、EditorGUILayout TagField
TextArea() EditorGUI、EditorGUILayout、GUI、GUILayout TextField,其中 multiline 设置为 true、style.whiteSpace 设置为 Normal 以及 ScrollView.verticalScrollerVisibility 设置为 Auto
TextField() EditorGUI、EditorGUILayout、GUI、GUILayout TextField,其中 multiline 设置为 true 以及 style.whiteSpace 设置为 NoWrap
Toggle() EditorGUI、EditorGUILayout、GUI、GUILayout Toggle
ToggleGroupScope EditorGUILayout UI 工具包中通常不需要范围。参见 BeginToggleGroup()
ToggleLeft() EditorGUI、EditorGUILayout Toggle,但不是设置 label,而是设置 text
Toolbar() GUI, GUILayout 无等效项。
UnfocusWindow() GUI 请参阅 Window()
Vector2Field() EditorGUI、EditorGUILayout Vector2Field
Vector2IntField() EditorGUI、EditorGUILayout Vector2IntField
Vector3Field() EditorGUI、EditorGUILayout Vector3Field
Vector3IntField() EditorGUI、EditorGUILayout Vector3IntField
Vector4Field() EditorGUI、EditorGUILayout Vector4Field
VerticalScope EditorGUILayout、GUILayout 在 UI Toolkit 中通常不需要作用域。请参阅 BeginArea()
VerticalScrollbar() GUI, GUILayout Scroller,其中 direction 设置为 Vertical
VerticalSlider() GUI, GUILayout Sliderdirection 设为 Vertical
Width() GUILayout VisualElement.style.width
窗口 GUI, GUILayout 无等效项。

Additional resources

从 Unity UI (uGUI) 迁移到 UI 工具包
Unity UI