本指南面向的是了解 即时模式 GUI (IMGUI) 的开发者,以便他们迁移到 UI(用户界面)允许用户与您的应用程序进行交互。Unity 目前支持三个 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 入门。
使用 IMGUIContainer
将 IMGUI 代码放在 VisualElement
内。OnGUI()
中能做的一切都得到支持。
您可以排列多个 IMGUIContainer
并通过混合使用 GUILayout
和 UI Toolkit 布局对其进行布局。请注意,不可能在 IMGUIContainer
中添加 VisualElement
实例。
下表列出了 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.position 至 Position.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.top 和 style.left 来定义位置。设置 style.width 和 style.height 来定义大小。设置 style.backgroundColor 来设置颜色。 |
DrawTexture() |
GUI |
Image 。将 tintColor 代替 color 。没有 false alphaBlend 的等价项。没有 borderWidth 、borderWidths 、borderRadius 或 borderRadiuses 的等价项。 |
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 |
Scroller ,direction 设置为 Horizontal 。 |
HorizontalSlider() |
GUI, GUILayout |
Slider ,direction 设置为 Horizontal |
InspectorTitlebar() |
EditorGUI、EditorGUILayout | 无等效项。 |
IntField() |
EditorGUI、EditorGUILayout | IntegerField |
IntPopup() |
EditorGUI、EditorGUILayout | 无等效项。 |
IntSlider() |
EditorGUI、EditorGUILayout | SliderInt |
Label() |
GUI, GUILayout | Label |
LabelField() |
EditorGUI、EditorGUILayout |
TextField ,isReadOnly 设置为 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 ,其中 isSelectable 和 focusable 设置为 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 |
Slider 和 direction 设为 Vertical 。 |
Width() |
GUILayout | VisualElement.style.width |
窗口 |
GUI, GUILayout | 无等效项。 |