Version: Unity 6.0 (6000.0)
언어 : 한국어
ListView 없이 리스트에 바인딩
커스텀 컨트롤을 커스텀 데이터 유형에 바인딩

커스텀 컨트롤 바인딩

버전: 2021.3+

이 예제에서는 커스텀 컨트롤을 네이티브 Unity 유형에 바인딩하는 방법을 보여 줍니다.

개요 예시

이 예시에서는 2D 이미지를 표시하는 커스텀 컨트롤을 생성합니다. 새 에셋 유형에 대해 커스텀 에디터에서 커스텀 컨트롤을 사용하고 새 유형의 에셋에 있는 필드에 커스텀 컨트롤을 바인딩합니다.

이 예시에서 생성한 완성된 파일은 이 GitHub 저장소에서 찾을 수 있습니다.

선행 조건

이 가이드는 Unity 에디터, UI 툴킷, C# 스크립팅에 익숙한 개발자를 위한 가이드입니다. 시작하기 전에 먼저 다음을 숙지하십시오.

직렬화된 오브젝트 생성

Texture2D가 포함된 직렬화된 오브젝트를 생성합니다.

  1. 임의의 템플릿을 사용하여 Unity 프로젝트를 생성합니다.
  2. 프로젝트 창에서 파일을 저장할 bind-custom-control이라는 폴더를 만듭니다.
  3. 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로 스타일을 지정합니다.

  1. 해당 폴더에 Editor라는 이름의 폴더를 만듭니다.
  2. Editor 폴더에 TexturePreviewElement.cs라는 이름의 C# 스크립트를 생성합니다.
  3. 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);
                }
            }
        }
    }
}
  1. Editor 폴더에 Resources라는 이름의 폴더를 만듭니다.
  2. Resources 폴더에서 texture_preview_element.uss라는 이름의 StyleSheet 문서를 생성하고 해당 콘텐츠를 다음과 같이 바꿉니다.
.texture-preview-element {
    width: 200px;
    height: 200px;
}

.texture-preview-element > .unity-image {
    flex-grow: 1;
}

인스펙터 UI 만들기

인스펙터 UI를 만들고 커스텀 컨트롤을 해당 Texture2D 오브젝트에 바인딩합니다.

  1. 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();
        }
    }
}

UXML을 사용한 바인딩 설정

TexturePreviewElement를 사용하여 UXML 파일을 생성하고 binding-path 프로퍼티를 texture로 설정합니다. 그러면 TexturePreviewElement가 TextureAsset.texture에 바인딩됩니다.

  1. Editor 폴더에 texture_asset_editor.uxml이라는 이름의__ UI__(사용자 인터페이스) 사용자가 애플리케이션과 상호 작용하도록 해 줍니다. Unity는 현재 3개의 UI 시스템을 지원합니다. 자세한 정보
    See in Glossary
    문서를 생성하고 해당 콘텐츠를 다음으로 바꿉니다.
<ui:UXML xmlns:ui="UnityEngine.UIElements" xmlns:example="UIToolkitExamples" editor-extension-mode="True">
    <example:TexturePreviewElement binding-path="texture" />
</ui:UXML>
  1. 프로젝트 창에서 TextureAssetEditor.cs를 선택합니다.
  2. texture_asset_editor.uxml을 인스펙터의 비주얼 트리로 드래그합니다.

바인딩 테스트

  1. 메뉴에서 Assets > Create > UIToolkitExamples > TextureAsset을 선택합니다. 그러면 TextureAsset의 인스턴스가 생성됩니다.
  2. 새 TextureAsset 오브젝트를 선택합니다. 인스펙터에서 텍스처 미리 보기 요소를 확인할 수 있습니다. 필드에 텍스처 에셋 레퍼런스를 넣으면 필드 위에 미리 보기가 표시됩니다. UI의 텍스처 미리 보기 요소에서 에셋 레퍼런스를 변경하면 TextureAsset.texture가 변경됩니다.

추가 리소스

ListView 없이 리스트에 바인딩
커스텀 컨트롤을 커스텀 데이터 유형에 바인딩