버전:2021.3+
이 예제에서는 커스텀 컨트롤을 네이티브 Unity 타입에 바인딩하는 방법을 보여 줍니다.
이 예제에서는 2D 이미지를 표시하는 커스텀 컨트롤을 만듭니다.새 에셋 타입에 대해 커스텀 에디터에서 커스텀 컨트롤을 사용하고 새 타입의 에셋에 있는 필드에 커스텀 컨트롤을 바인딩합니다.
이 예제에서 생성한 완성된 파일은 GitHub 저장소에서 확인할 수 있습니다.
이 가이드는 Unity 에디터, UI 툴킷, C# 스크립팅에 익숙한 개발자용입니다.시작하기 전에 먼저 다음을 숙지하십시오.
Texture2D가 포함된 직렬화된 오브젝트를 생성합니다.
임의의 템플릿을 사용하여 Unity 프로젝트를 생성합니다.
프로젝트(Project) 창에서 파일을 저장할 폴더 이름을 ’bind-custom-control’로 지정합니다.
TextureAsset.cs라는 이름의 C# 스크립트를 생성하고 그 내용을 다음과 같이 바꿉니다.
using UnityEngine;
namespace UIToolkitExamples
{
    [CreateAssetMenu(menuName = "UIToolkitExamples/TextureAsset")]
    public class TextureAsset :ScriptableObject
    {
        public Texture2D texture;
        public void Reset()
        {
            texture = null;
        }
    }
}
C#을 사용해 2D 텍스처 에셋에 대한 레퍼런스를 나타내는 커스텀 컨트롤을 생성하여 USS로 스타일을 지정합니다.
Editor라는 이름의 폴더를 만듭니다.TexturePreviewElement.cs라는 이름의 C# 스크립트를 생성합니다.TexturePreviewElement.cs의 콘텐츠를 다음으로 바꿉니다.using System;
using UnityEditor.UIElements;
using UnityEngine;
using UnityEngine.UIElements;
using Object = UnityEngine.Object;
namespace UIToolkitExamples
{
    public class TexturePreviewElement :BindableElement, INotifyValueChanged<Object>
    {
        public new class UxmlTraits :BindableElement.UxmlTraits { }
        public new class UxmlFactory :UxmlFactory<TexturePreviewElement, UxmlTraits> { }
        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);
                }
            }
        }
    }
}
Editor 폴더에 Resources라는 이름의 폴더를 만듭니다.
Resources 폴더에 texture_preview_element.uss라는 이름의 StyleSheet를 생성하고 콘텐츠를 다음으로 바꿉니다.
.texture-preview-element {
    width:200px;
    height:200px;
}
.texture-preview-element > .unity-image {
    flex-grow:1;
}
인스펙터 UI를 만들고 커스텀 컨트롤을 해당 Texture2D 오브젝트에 바인딩합니다.
Editor 폴더에서 TextureAssetEditor.cs라는 이름의 C# 스크립트를 생성하고 해당 콘텐츠를 다음과 같이 바꿉니다.
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();
        }
    }
}
TexturePreviewElement를 사용하여 UXML 파일을 생성하고 binding-path 프로퍼티를 texture로 설정합니다.이렇게 하면 TexturePreviewElement가 TextureAsset.texture에 바인딩됩니다.
Editor 폴더에 texture_asset_editor.uxml이라는 이름의 UI 문서를 생성하고 해당 콘텐츠를 다음과 같이 바꿉니다.
<ui:UXML xmlns:ui="UnityEngine.UIElements" xmlns:example="UIToolkitExamples" editor-extension-mode="True">
    <example:TexturePreviewElement binding-path="texture" />
</ui:UXML>
프로젝트 창에서 TextureAssetEditor.cs를 선택합니다.
texture_asset_editor.uxml을 인스펙터의 Visual Tree로 드래그합니다.
TextureAsset 인스턴스가 생성됩니다.TextureAsset.texture가 변경됩니다.