Unity 6.3
0 онлайн 111 гостей 3 в системе
Вход
UI системы Шаг 224 из 317

Введение в привязку данных SerializedObject

Вы можете использовать SerializedObject система привязки данных для привязки сериализированные свойстваЭто означает, что вы можете связать визуальные элементы с следующими объектами, которые совместимы с Система сериализации:

  • Определенные пользователем классы ,ScriptableObject,
  • Определенные пользователем классы ,MonoBehaviour,
  • Нативные типы компонентов Unity
  • Основные типы ассетов Unity
  • Примитивные типы C#, такие как int, boolили float.
  • Основные типы Unity, такие как Vector3, Colorили Object.

Привязка значения

Вы можете связать только value свойство визуальных элементов, которые реализуют INotifyValueChanged интерфейс. Например, вы можете привязать TextField.value к а string, но вы не можете связать TextField.name к а string.

Вы можете связать между объектом и любым визуальным элементом, который либо происходит от BindableElement или осуществляет IBindable interface.

Создание привязки

Для создания привязки либо вызывает Bind() или BindProperty().

Вызов Bind()

Вы можете вызвать Bind() для привязки элемента к SerializedObject. Перед привязкой элемента вы должны установить путь привязки и создать SerializedObject.

Используйте этот метод, если у вас нет легкого доступа к SerializedProperty для привязки. См. Создание привязки с помощью сценария C# для примера.

Метод расширения Bind() устанавливает всю иерархию визуальных элементов с указанными свойствами bindingPath. Вы можете вызвать метод Bind() на одном элементе или родителе иерархии, которую вы хотите связать. Например, вы можете вызвать Bind() на rootVisualElement окна Редактора. Это связывает все дочерние элементы с указанными свойствами bindingPath.

Не звоните Bind от Editor.CreateInspectorGUI или PropertyDrawer.CreatePropertyGUI override. Bind автоматически вызывает визуальные элементы, которые возвращают эти методы.

Вызов Unbind()

Метод Unbind() останавливает отслеживание значений для элемента и всех его прямых и косвенных дочерних элементов. В целом, вам не нужно вызывать Unbind(), поскольку отслеживание останавливается, когда пользователь закрывает окно Inspector или редактора. Вызовите Unbind(), если вы должны привязать элементы к различным целям в течение их жизненного цикла.

Если вы построите InspectorElement в C#, вызвав его конструктор, привязка происходит во время вызова конструктора. Если вы хотите перепривязать InspectorElement после того, как он был построен, вы должны вызвать Unbind(), а затем либо явно вызвать Bind(), либо позволить операции привязки родительского объекта создать привязку.

Установить путь привязки

Если вы вызываете Bind() для создания привязки, вы должны установить путь привязки визуального элемента на имя свойства объекта, к которому вы хотите связать.

Например:

  • Если у вас есть следующий скрипт компонента:

    using UnityEngine;
    
    public class MyComp : MonoBehaviour
    {
        [SerializeField]
        int m_Count;
    }
    

    Чтобы привязать визуальный элемент к m_Count, установите путь привязки на m_Count.

  • Если вы хотите привязать визуальный элемент к свойству GameObject, которое называется m_Name, установите путь привязки в m_Name.

Вы можете установить путь привязки в UI Builder, UXML или с помощью скрипта C#:

Вызов BindProperty()

Вы можете вызвать BindProperty() для непосредственной привязки элемента к SerializedProperty.

Используйте этот метод, если у вас уже есть SerializedProperty объекта, и особенно, если вы переходите через свойства объекта, SerializedObject построить UI динамически. См. Привязка без пути привязки например.

Привязка элементов к вложенным свойствам

Вы можете привязать визуальный элемент к вложенным свойствам в исходном объекте. Для этого объедините путь привязки элемента с путем привязки первого предка. Используйте этот метод со следующими элементами:

Пример см. в Привязка к вложенным свойствам.

Получение обратных вызовов при изменении значений

Вы можете создать привязку для получения обратного вызова при изменении связанного серийного свойства. Для этого используйте метод расширения TrackPropertyValue(), доступный для любого VisualElement. Этот метод регистрирует обратный вызов, который выполняется при изменении предоставленного SerializedProperty. См. Получение обратных вызовов при изменении серийного свойства для примера.

Вы также можете создать привязку для получения обратного вызова при изменении любых свойств связанного серийного объекта. Для этого используйте метод расширения TrackSerializedObjectValue(), доступный для любого VisualElement. Этот метод регистрирует обратный вызов, который выполняется при изменении предоставленного SerializedObject. См. Получение обратных вызовов при изменении любых свойств для примера.

Привязка пользовательских элементов

Вы можете создавать настраиваемые элементы и привязывать их к серийным свойствам через связывание значений система.

Чтобы создать связываемые пользовательские элементы:

  1. Заявляет пользовательский элемент.
  2. Наследовать элемент от BindableElement или осуществить IBindable interface.
  3. Осуществление INotifyValueChanged interface.
  4. Осуществление SetValueWithoutNotify() метода INotifyValueChanged interface.
  5. Осуществление value свойства, находящегося INotifyValueChanged interface.

См. Создание и стилизация пользовательского контроля для примера.

Примечание: Вы не можете привязать пользовательские типы данных непосредственно к пользовательским элементам, потому что система привязки только позволяет вам привязать элемент к типу, поддерживаемому SerializedPropertyType из enum. Это значит, что вы не можете объявить класс или структуру — например, структуру с именем MyStruct, и привязать его к элементу, реализующему INotifyValueChanged<MyStruct>. Однако, вы можете связать к serializable вложенным свойствам пользовательских типов данных. Это включает полиморфизм serialization (когда поле использует [SerializeReference] атрибут). См. Привязка настраиваемого контроля к настраиваемому типу данных например.

Время связывания

В зависимости от типа UI, который вы создаете, привязка происходит в разное время. Это называется временем привязки.

В следующей таблице описывается время привязки контроля:

Состояние Автоматическое время привязки (при условии установки пути привязки)
Ан InspectorElement построен в C# Во время constructor вызова
Дочерний элемент, который находится под возвращаемым значением CreateInspectorGUI() или CreatePropertyGUI(), когда эти методы возвращают После CreateInspectorGUI() или CreatePropertyGUI() возвращается
Дочерний элемент, который находится под элементом, когда Bind() или BindProperty() вызван на родительском элементе Во время вызова Bind() или BindProperty()
Прочие Нет автоматической привязки; вы должны привязать элемент или одного из его родителей вручную

Ниже приведены рекомендации по созданию привязки, касающиеся времени привязки:

  • Если вы создаете пользовательский Editor или обычная PropertyDrawer, установить пути связывания элементов вместо вызова Bind() или BindProperty() на любых визуальных элементах, которые находятся в визуальное дерево к концу основного текста CreateInspectorGUI() или CreatePropertyGUI(). Эти элементы связываются автоматически после CreateInspectorGUI() или CreatePropertyGUI() Однако, если вы добавите какие-либо элементы в визуальное дерево после этой точки, вызов Bind() или BindProperty() чтобы связать их.
  • Если вы создаете любой другой тип UI, вызовите Bind() или BindProperty() независимо от времени добавления элементов в визуальное дерево. Если вы вызываете Bind() или BindProperty() и привязываете несколько контроллеров одновременно, установите путь привязки каждого контроллера, а затем вызовите Bind() на родительском элементе самого низкого уровня, который охватывает все контроллеры. Bind() привязывает элемент, на котором он вызван, если у него есть путь привязки, и рекурсивно привязывает все его дочерние элементы, если у них есть пути привязки. Чтобы избежать негативного воздействия на производительность, не привязывайте визуальный элемент методом Bind() более одного раза.

Привязка к базовому полю серийного свойства

Когда вы используете автосвойство, компилятор автоматически генерирует вспомогательное поле с таким именем, как <PropertyName>k__BackingField. Это поле явно не видно в вашем коде, но на него можно ссылаться при необходимости, как в сценариях привязки.

Например, в следующем примере определяется автосвойство SomeProp и оно сериализируется:

[field: SerializeField] 
public float SomeProp 
{ 
    get; 
    private set; 
}

Компилятор генерирует следующее поле:

[SerializedField]
private float <SomeProp>k__BackingField;

public float SomeProp
{
    get => <SomeProp>k__BackingField;
    set => <SomeProp>k__BackingField = value;
}

Для привязки к <SomeProp>k__BackingField в UXML, вы должны спасти < и >, так как они зарезервированы для тегов. Например, установите binding-path следующим образом:

<editor:PropertyField name="some-prop" binding-path="&lt;SomeProp&gt;k__BackingField"/>

Обязательные примеры

Попробуйте следующие примеры, чтобы узнать, как писать код с привязкой данных:

Дополнительные ресурсы