Привязка настраиваемого контроля
Версия: 2021.3+
В этом примере показано, как связать пользовательский контроллер с основным типом Unity.
Примерный обзор
В примере создается пользовательский контроллер, который отображает изображение 2D. Он использует пользовательский контроллер в пользовательском редакторе для нового типа ассета и связывает пользовательский контроллер с полем в ассете нового типа.
Вы можете найти завершенные файлы, созданные этим примером, в хранилище GitHub.
Предварительные условия
Это руководство предназначено для разработчиков, знакомых со скриптами Unity Editor, UI Toolkit и C#. Перед началом работы ознакомьтесь со следующим:
Создание серийного объекта
Создайте серийный объект, содержащий Texture2D.
- Создайте проект Unity с любым шаблоном.
- В окне Project создайте папку с именем
bind-custom-controlдля хранения файлов. - Создайте скрипт C# с именем
TextureAsset.csи замените его содержимое следующим:
using UnityEngine;
namespace UIToolkitExamples
{
[CreateAssetMenu(menuName = "UIToolkitExamples/TextureAsset")]
public class TextureAsset : ScriptableObject
{
public Texture2D texture;
public void Reset()
{
texture = null;
}
}
}
Создание и настройка стиля пользовательского элемента управления
Создайте пользовательский контроллер с C#, который представляет собой ссылку на текстуру 2D, и стилизируйте его с USS.
- В этой папке создайте папку с именем
Editor. - В течение Редактор папка, создать C# скрипт назван
TexturePreviewElement.cs. - Заменить содержимое
TexturePreviewElement.csследующим текстом:
using System;
using UnityEditor.UIElements;
using UnityEngine;
using UnityEngine.UIElements;
using Object = UnityEngine.Object;
namespace UIToolkitExamples
{
[UxmlElement]
public partial class TexturePreviewElement : BindableElement, INotifyValueChanged<Object>
{
public static readonly string ussClassName = "texture-preview-element";
Image m_Preview;
ObjectField m_ObjectField;
Texture2D m_Value;
public TexturePreviewElement()
{
AddToClassList(ussClassName);
// Create a preview image.
m_Preview = new Image();
Add(m_Preview);
// Create an ObjectField, set its object type, and register a callback when its value changes.
m_ObjectField = new ObjectField();
m_ObjectField.objectType = typeof(Texture2D);
m_ObjectField.RegisterValueChangedCallback(OnObjectFieldValueChanged);
Add(m_ObjectField);
styleSheets.Add(Resources.Load<StyleSheet>("texture_preview_element"));
}
void OnObjectFieldValueChanged(ChangeEvent<Object> evt)
{
value = evt.newValue;
}
public void SetValueWithoutNotify(Object newValue)
{
if (newValue == null || newValue is Texture2D)
{
// Update the preview Image and update the ObjectField.
m_Value = newValue as Texture2D;
m_Preview.image = m_Value;
// Notice that this line calls the ObjectField's SetValueWithoutNotify() method instead of just setting
// m_ObjectField.value. This is very important; you don't want m_ObjectField to send a ChangeEvent.
m_ObjectField.SetValueWithoutNotify(m_Value);
}
else throw new ArgumentException($"Expected object of type {typeof(Texture2D)}");
}
public Object value
{
get => m_Value;
// The setter is called when the user changes the value of the ObjectField, which calls
// OnObjectFieldValueChanged(), which calls this.
set
{
if (value == this.value)
return;
var previous = this.value;
SetValueWithoutNotify(value);
using (var evt = ChangeEvent<Object>.GetPooled(previous, value))
{
evt.target = this;
SendEvent(evt);
}
}
}
}
}
- В течение Редактор папка, создать папку с названием
Resources. - В течение Ресурсы папка, создать StyleSheet названный
texture_preview_element.ussи заменить его содержание следующим:
.texture-preview-element {
width: 200px;
height: 200px;
}
.texture-preview-element > .unity-image {
flex-grow: 1;
}
Создать Inspector UI
Создайте объект Inspector UI и привязайте пользовательский контроллер к объекту Texture2D.
- В течение Редактор папка, создать C# скрипт назван
TextureAssetEditor.csи заменить его содержание следующим:
using UnityEditor;
using UnityEngine.UIElements;
using UnityEngine;
namespace UIToolkitExamples
{
[CustomEditor(typeof(TextureAsset))]
public class TextureAssetEditor : Editor
{
[SerializeField]
VisualTreeAsset m_VisualTree;
public override VisualElement CreateInspectorGUI()
{
return m_VisualTree.CloneTree();
}
}
}
Установите привязку с помощью UXML
Создайте файл UXML с TexturePreviewElement и установите свойство binding-path на texture. Это привязывает TexturePreviewElement к TextureAsset.texture.
- В течение Редактор папка, создать UI Документ назван
texture_asset_editor.uxmlи заменить его содержание следующим:
<ui:UXML xmlns:ui="UnityEngine.UIElements" xmlns:example="UIToolkitExamples" editor-extension-mode="True">
<example:TexturePreviewElement binding-path="texture" />
</ui:UXML>
- В окне Project выберите TextureAssetEditor.cs.
- Перетащите texture_asset_editor.uxml в Визуальное Дерево в Inspector.
Проверка привязки
- В меню выберите Ассеты > Создать > UIToolkitExamples > TextureAsset. Это создаст экземпляр
TextureAsset. - Выберите новый объект TextureAsset. В Inspectorвы можете увидеть Элемент Предварительного Просмотра Текстуры. Если вы помещаете ссылку на ресурс текстуры в поле, вы можете увидеть предварительный просмотр над полем. Если вы измените ссылку на ресурс в Элементе Предварительного Просмотра Текстуры в UI, то
TextureAsset.textureизменится.