Миграция из Немедленного Режима GUI (IMGUI) в UI Toolkit
Это руководство предназначено для разработчиков, имеющих опыт работы с Immediate Mode GUI (IMGUI), чтобы перейти на UI Toolkit. Это руководство посвящено Редактору UI, но его информация может также применяться к runtime UI.
Основные различия
Ориентированный на код против ориентированного на UI
IMGUI управляется кодом при помощи вызовов функции OnGUI в скрипте C#, реализующем его. UI Toolkit предоставляет больше возможностей для создания Редактора UI. С помощью UI Toolkit вы определяете поведение в скриптах C#. Однако, при определении элементов и стилей UI, в дополнение к C#, вы можете визуально определить элементы управления UI в UI Builder или написать в текстовый файл, похожий на XML (называемый UXML) напрямую. Для получения дополнительной информации см. Начало работы с UI Toolkit.
Немедленный режим в сравнении с сохраненным режимом
С IMGUI, вы описываете UI дерево, когда UI перекрашивается в пределах OnGUI() Вы должны вызвать эту функцию, когда событие входит в UI или когда вы перекрасите UI. Нет никакой постоянной информации, касающейся UI между различными событиями. В то время как, вы создаете визуальные элементы с UI Toolkit в древесной структуре, называемой Визуальное дерево. Информация в Визуальных Деревьях сохраняется постоянно.
Постоянство при изменениях состояния
IMGUI основан на функции OnGUI(), которая запускается по крайней мере один раз в каждом кадре. Вы определяете внешний вид и поведение UI для каждого возможного кадра. Тело OnGUI() может содержать много условий и различных состояний.
UI Toolkit работает в системе, управляемой событиями. Вы задаёте внешний вид интерфейса в его состоянии по умолчанию и описываете поведение интерфейса в ответ на события. Любые изменения, которые вы вносите в UI Toolkit, приводят к постоянным изменениям состояния вашего интерфейса.
Например, объявление кнопки в 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. Обратите внимание, что нельзя добавлять экземпляры VisualElement внутрь IMGUIContainer.
IMGUIContainerПреобразование из IMGUI в UI Toolkit
В следующей таблице перечислены эквивалентные функции между IMGUI и UI Toolkit:
| Действия | IMGUI | UI Toolkit |
|---|---|---|
| Создать Окно редактора | EditorWindow.OnGUI() |
EditorWindow.CreateGUI() |
| Создать Ящик свойства или атрибут свойства | PropertyDrawer.OnGUI() |
PropertyDrawer.CreatePropertyGUI() |
| Создать пользовательский редактор для Inspector | Editor.OnInspectorGUI() |
Editor.CreateInspectorGUI() |
В следующей таблице перечислены эквивалентные методы, классы и атрибуты между IMGUI и UI Toolkit:
| IMGUI | IMGUI пространства имен | UI Toolkit |
|---|---|---|
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 в качестве замены для серийного поля в пользовательском Inspector, используйте 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() для привязки простого элемента управления к серийному свойству, вы можете сделать это в UI Toolkit, вызвав BindProperty(), установив bindingPathили установив атрибут binding-path UXML. Если вы используете 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. Нет эквивалента для ложного alphaBlend. |
DropdownButton() |
EditorGUI, EditorGUILayout | Нет точного эквивалента. Используйте полноценные DropdownFieldвместо простого DropdownButton(). |
DropShadowLabel() |
EditorGUI | Label со значениями тени, установленными в style.textShadow. |
EditorToolbar() |
EditorGUILayout | Создайте Toolbar с одним 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 | VisualElement.scaledPixelPerPoint |
PointsToPixels() |
EditorGUIUtility | используйте VisualElement.scaledPixelPerPoint для выполнения преобразования. |
pixelsPerPoint |
EditorGUIUtility | используйте VisualElement.scaledPixelPerPoint для выполнения преобразования. |
Popup() |
EditorGUI, EditorGUILayout | PopupField<T0> |
ProgressBar() |
EditorGUI | ProgressBar |
PropertyField() |
EditorGUI, EditorGUILayout | PropertyField |
PropertyScope |
EditorGUI | Области обычно не нужны в UI Toolkit. См. BeginProperty(). |
RectField() |
EditorGUI, EditorGUILayout | RectField |
RectIntField() |
EditorGUI, EditorGUILayout | RectIntField |
RepeatButton() |
GUI, GUILayout | RepeatButton |
ScrollTo() |
GUI | ScrollView.ScrollTo() или ScrollView.scrollOffset |
ScrollViewScope |
EditorGUILayout, GUI, GUILayout | Области обычно не нужны в UI Toolkit. См. 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 Toolkit. См. 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 |
Window() |
GUI, GUILayout | Не эквивалент. |