Перейти к основному содержимому

VisualElement Extensions

Интерфейс UI Toolkit одной цепочкой вызовов — без отдельной строки на каждое свойство и стиль.

Быстрый старт​

До — Unity APIПосле — FastTools
var title = new Label("Ability Config");
title.style.fontSize = 14;

var header = new VisualElement();
header.style.paddingLeft = 12;
header.style.paddingRight = 12;
header.style.paddingTop = 10;
header.style.paddingBottom = 10;
header.Add(title);
var header = new VisualElement()
.SetPaddingX(12)
.SetPaddingY(10)
.AddChild(new Label("Ability Config")
.SetFontSize(14));

Цепочка сохраняет тип: new Button().SetText("Create") — это Button, а AddChild возвращает родителя, а не добавленный элемент.

Имена методов​

UnityFastTools
tooltip = "Mana cost"SetTooltip("Mana cost")
isDelayed = trueSetDelayed(true)
style.fontSize = 14SetFontSize(14)
clicked += RefreshAddClicked(Refresh)
bindItem = BindRowSetBindItem(BindRow)
Focus()FocusSelf()
Init(theme)Initialize(theme)

Остальные методы Unity переименованы по смыслу — они в разделах ниже. Полный список методов — в справочнике API.

Дочерние элементы​

UnityFastTools
AddAddChild, AddChildren
InsertInsertChild, InsertChildren
RemoveRemoveChild, RemoveChildren
RemoveAtRemoveChildAt
ClearClearChildren
До — Unity APIПосле — FastTools
if (isFree)
body.Add(helpBox);
body.AddChildIf(isFree, helpBox);

Вариант …If есть у каждого метода из первой таблицы.

Стили​

До — Unity APIПосле — FastTools
header.style.marginTop = 4;
header.style.marginBottom = 4;
header.style.borderBottomWidth = 1;
header
.SetMarginY(4)
.SetBorderWidth(bottom: 1);
все стороны

Остальные методы стилей работают по тому же принципу.

Цвет из строки и ассеты из Resources​

До — Unity APIПосле — FastTools
if (ColorUtility.TryParseHtmlString(
"#FFC24D", out var color))
badge.style.color = color;
badge.SetColor("#FFC24D");
root.style.backgroundImage = Resources
.Load<Texture2D>("UI/Card");
root.SetBackgroundImageFromResources(
"UI/Card");

Вариант …FromResources есть также у SetImage, SetSprite, SetVectorImage, AddStyleSheet и RemoveStyleSheet.

Жирный и курсив​

SetNormalUnityFontStyleAndWeight() сбрасывает оба флага; остальные пресеты меняют один флаг и сохраняют второй:

МетодМеняет
AddBold…Normal → Bold, Italic → BoldAndItalic
RemoveBold…Bold → Normal, BoldAndItalic → Italic
AddItalic…Normal → Italic, Bold → BoldAndItalic
RemoveItalic…Italic → Normal, BoldAndItalic → Bold
примечание

Пресеты читают текущее значение из style элемента, а не итоговый стиль: начертание, заданное в USS, считается Normal.

USS-классы и таблицы стилей​

UnityFastTools
AddToClassListAddClass
RemoveFromClassListRemoveClass
ToggleInClassListToggleClass
EnableInClassListEnableClass
ClearClassListClearClasses
styleSheets.AddAddStyleSheet
styleSheets.RemoveRemoveStyleSheet

Значения и события​

UnityFastTools
value = 10SetValue(10)
SetValueWithoutNotify(10)SetValue(10, notify: false)
RegisterValueChangedCallbackAddValueChanged
UnregisterValueChangedCallbackRemoveValueChanged
  • AddValueChanged(evt => …) не требует аргументов типа: перегрузки есть для всех полей Unity, а при установленном com.unity.mathematics — и для его типов;
  • для своих типов — SetValue<T, TValue>(…) и AddValueChanged<TField, TValue>(…).

Фокус​

До — Unity APIПосле — FastTools
if (manaCost.focusController?
.focusedElement == manaCost)
Refresh();
if (manaCost.IsFocused())
Refresh();

Манипуляторы​

До — Unity APIПосле — FastTools
title.AddManipulator(
new Clickable(Refresh));
title.AddClickable(Refresh);
title.AddManipulator(
new KeyboardNavigationManipulator(
OnNavigate));
title.AddKeyboardNavigationManipulator(
OnNavigate);
title.AddManipulator(
new ContextualMenuManipulator(
BuildMenu));
title.AddContextualMenuManipulator(
BuildMenu);
var clickable = new Clickable(Refresh);
title.AddManipulator(clickable);
title.RemoveManipulator(clickable);
title.AddClickable(
Refresh, out var clickable);
title.RemoveManipulatorSelf(clickable);

Расширения редактора​

До — Unity APIПосле — FastTools
manaCost.bindingPath = "_manaCost";
manaCost.Bind(serializedObject);
manaCost.BindTo(
serializedObject, "_manaCost");
manaCost.bindingPath = "_manaCost";
manaCost.SetBindingPath(
"_manaCost");
manaCost.BindProperty(property);
manaCost.BindPropertyTo(property);
manaCost.Unbind();
manaCost.UnbindFrom();

У PropertyField есть SetLabel и AddValueChanged / RemoveValueChanged с SerializedPropertyChangeEvent:

var manaCost = new PropertyField(
serializedObject.FindProperty("_manaCost"))
.SetLabel("Mana cost")
.AddValueChanged(_ => Refresh());

Для записи в свойство из собственного кода используйте SerializedProperty Extensions.

Открыть скрипт по двойному клику​

AddOpenScriptCommand открывает в IDE скрипт MonoBehaviour или ScriptableObject по двойному клику левой кнопкой; для других объектов ничего не добавляет:

title.AddOpenScriptCommand(target);

Окно элемента​

До — Unity APIПосле — FastTools
var panel = title.panel;
var window = Resources
.FindObjectsOfTypeAll<EditorWindow>()
.FirstOrDefault(w => panel ==
w.rootVisualElement.panel);
if (!window)
window = EditorWindow.focusedWindow;
if (!window)
window = EditorWindow.mouseOverWindow;
var window = title.GetOwnerWindow();

Собственные свойства USS​

До — Unity APIПосле — FastTools
if (evt.customStyle.TryGetValue(
ThemeProperty, out var raw)
&& Enum.TryParse(raw,
ignoreCase: true,
out PreviewTheme theme))
ApplyTheme(theme);
if (evt.customStyle.TryGetByEnum(
ThemeProperty,
out PreviewTheme theme))
ApplyTheme(theme);

Пример в пакете​

Окно каталога и инспектор AbilityConfig в примере EditorTools собраны на этих расширениях.

Окно Ability Catalog из примера EditorToolsОкно Ability Catalog из примера EditorTools