바인딩의 목적은 오브젝트 내 프로퍼티를 표시되는 UI와 동기화하는 것입니다. 바인딩 은 프로퍼티와 해당 프로퍼티를 수정하는 시각 컨트롤 간의 연결을 의미합니다.
바인딩은 오브젝트, 그리고 BindableElement에서 파생되거나 IBindable 인터페이스를 구현하는 UIElement 간에 이루어집니다.
UnityEditor.UIElements 네임스페이스에서:
기본 클래스:
컨트롤:
UnityEngine.UIElements 네임스페이스에서:
기본 클래스
컨트롤
바인딩은 위에 나열된 네임스페이스 중 하나의 컨트롤을 사용하는 동안 다음 단계에 따라 이루어집니다.
다음 코드 스니핏은 C# 코드로 바인딩을 생성하는 방법을 보여줍니다. 이 스니핏(코드 조각)을 사용하려면 이 예제를 에디터 폴더에 C# 파일로 저장하십시오. C# 파일의 이름은 SimpleBindingExample.cs로 지정해야 합니다.
SimpleBindingExample.cs의 콘텐츠:
using UnityEditor;
using UnityEngine;
using UnityEditor.UIElements;
using UnityEngine.UIElements;
namespace UIElementsExamples
{
   public class SimpleBindingExample : EditorWindow
   {
       TextField m_ObjectNameBinding;
       [MenuItem("Window/UIElementsExamples/Simple Binding Example")]
       public static void ShowDefaultWindow()
       {
           var wnd = GetWindow<SimpleBindingExample>();
           wnd.titleContent = new GUIContent("Simple Binding");
       }
       public void OnEnable()
       {
           var root = this.rootVisualElement;
           m_ObjectNameBinding = new TextField("Object Name Binding");
           m_ObjectNameBinding.bindingPath = "m_Name";
           root.Add(m_ObjectNameBinding);
           OnSelectionChange();
       }
       public void OnSelectionChange()
       {
           GameObject selectedObject = Selection.activeObject as GameObject;
           if (selectedObject != null)
           {
               // Create serialization object
               SerializedObject so = new SerializedObject(selectedObject);
               // Bind it to the root of the hierarchy. It will find the right object to bind to...
               rootVisualElement.Bind(so);
               // ... or alternatively you can also bind it to the TextField itself.
               // m_ObjectNameBinding.Bind(so);
           }
           else
           {
               // Unbind the object from the actual visual element
               rootVisualElement.Unbind();
               // m_ObjectNameBinding.Unbind();
               // Clear the TextField after the binding is removed
               m_ObjectNameBinding.value = "";
           }
       }
   }
}
Unity에서 Window > UIElementsExamples > Simple Binding Example을 선택합니다. 이 창을 사용하여 씬 내 게임 오브젝트를 선택하고 표시된 TextField에서 이름을 수정할 수 있습니다.
이 섹션에서는 UXML 계층 구조 설정을 통해 바인딩을 사용하는 방법을 보여줍니다.
UXML에서 binding-path 속성은 TextField 컨트롤에서 정의됩니다. 이를 통해 컨트롤이 오브젝트의 유효한 프로퍼티에 바인딩됩니다.
SimpleBindingExample.uxml의 콘텐츠:
<UXML xmlns:ui="UnityEngine.UIElements">
 <ui:VisualElement name="top-element">
   <ui:Label name="top-label" text="UXML-Defined Simple Binding"/>
   <ui:TextField name="GameObjectName" label="Name" text="" binding-path="m_Name"/>
 </ui:VisualElement>
</UXML>
SimpleBindingExample.cs의 콘텐츠:
using UnityEditor;
using UnityEngine;
using UnityEditor.UIElements;
using UnityEngine.UIElements;
namespace UIElementsExamples
{
   public class SimpleBindingExampleUXML : EditorWindow
   {
       [MenuItem("Window/UIElementsExamples/Simple Binding Example UXML")]
       public static void ShowDefaultWindow()
       {
           var wnd = GetWindow<SimpleBindingExampleUXML>();
           wnd.titleContent = new GUIContent("Simple Binding UXML");
       }
       public void OnEnable()
       {
           var root = this.rootVisualElement;
           var visualTree = AssetDatabase.LoadAssetAtPath<VisualTreeAsset>("Assets/Editor/SimpleBindingExample.uxml");
           visualTree.CloneTree(root);
           OnSelectionChange();
       }
       public void OnSelectionChange()
       {
           GameObject selectedObject = Selection.activeObject as GameObject;
           if (selectedObject != null)
           {
               // Create serialization object
               SerializedObject so = new SerializedObject(selectedObject);
               // Bind it to the root of the hierarchy. It will find the right object to bind to...
               rootVisualElement.Bind(so);
           }
           else
           {
               // Unbind the object from the actual visual element
               rootVisualElement.Unbind();
               // Clear the TextField after the binding is removed
               // (this code is not safe if the Q() returns null)
               rootVisualElement.Q<TextField>("GameObjectName").value = "";
           }
       }
   }
}
InspectorElement는 인스펙터의 UIElement 버전으로 특정 타입의 Unity 오브젝트를 의미합니다. InspectorElement를 사용하여 오브젝트를 점검하면 다음과 같은 이점이 있습니다.
Assets/Editor/SimpleBindingExample.cs 아래에 있는 다른 간단한 바인딩 예제를 통해 이러한 프로세스의 사용 방법 및 개요를 확인할 수 있습니다.
Assets/Editor/SimpleBindingExample.cs의 콘텐츠:
using UnityEditor;
using UnityEngine;
using UnityEditor.UIElements;
namespace UIElementsExamples
{
   public class SimpleBindingExampleUXML : EditorWindow
   {
       [MenuItem("Window/UIElementsExamples/Simple Binding Example UXML")]
       public static void ShowDefaultWindow()
       {
           var wnd = GetWindow<SimpleBindingExampleUXML>();
           wnd.titleContent = new GUIContent("Simple Binding UXML");
       }
       TankScript m_Tank;
       public void OnEnable()
       {
           m_Tank = GameObject.FindObjectOfType<TankScript>();
           if (m_Tank == null)
               return;
           var inspector = new InspectorElement(m_Tank);
           rootVisualElement.Add(inspector);
       }
   }
}
이 코드는 TankScript 스크립트를 참조하고 InspectorElement를 사용합니다. TankScript 스크립트는 게임 오브젝트에 할당된 MonoBehaviour의 예제입니다.
Assets/TankScript.cs의 콘텐츠:
using UnityEngine;
[ExecuteInEditMode]
public class TankScript : MonoBehaviour
{
   public string tankName = "Tank";
   public float tankSize = 1;
   private void Update()
   {
       gameObject.name = tankName;
       gameObject.transform.localScale = new Vector3(tankSize, tankSize, tankSize);
   }
}
InspectorElement는 특정 UI를 통해 커스터마이즈됩니다. 이 작업은 TankEditor 스크립트를 통해 이루어집니다. TankEditor 스크립트는 TankScript 타입에 대한 커스텀 에디터를 정의합니다. 또한 TankEditor 스크립트는 계층 구조에 UXML 파일을 사용하고, USS 파일을 사용하여 인스펙터의 스타일을 지정합니다.
Assets/Editor/TankEditor.cs의 콘텐츠:
using UnityEditor;
using UnityEngine;
using UnityEngine.UIElements;
[CustomEditor(typeof(TankScript))]
public class TankEditor : Editor
{
   public override VisualElement CreateInspectorGUI()
   {
       var visualTree = Resources.Load("tank_inspector_uxml") as VisualTreeAsset;
       var uxmlVE = visualTree.CloneTree();
uxmlVE.styleSheets.Add(AssetDatabase.LoadAssetAtPath<StyleSheet>("Assets/Resources/tank_inspector_styles.uss"));
      return uxmlVE;
   }
}
Assets/Resources/tank_inspector_uxml.uxml의 콘텐츠:
<UXML xmlns:ui="UnityEngine.UIElements" xmlns:ue="UnityEditor.UIElements">
   <ui:VisualElement name="row" class="container">
       <ui:Label text="Tank Script - Custom Inspector" />
       <ue:PropertyField binding-path="tankName" name="tank-name-field" />
       <ue:PropertyField binding-path="tankSize" name="tank-size-field" />
   </ui:VisualElement>
</UXML>
tank_inspector_uxml.uxml UXML 파일은 바인딩을 지정합니다. 특히 PropertyFields 태그에 대한 각 binding-path 속성은 바인딩할 프로퍼티로 설정됩니다. UI에 표시되는 요소는 바인딩된 각 프로퍼티의 타입에 기반합니다.
Assets/Resources/tank_inspector_styles.uss의 콘텐츠:
.container {
   background-color: rgb(80, 80, 80);
   flex-direction: column;
}
Label {
   background-color: rgb(80, 80, 80);
}
TextField:hover {
   background-color: rgb(255, 255, 0);
}
FloatField {
   background-color: rgb(0, 0, 255);
}
tank_inspector_styles.uss USS 파일은 각 요소의 스타일을 지정합니다.
다음 표에는 PropertyField에서 지원되는 필드가 나와 있습니다. 각 필드에는 해당 데이터 타입이 들어 있습니다.
| 필드 | Type | 
|---|---|
| BoundsField | Bounds | 
| BoundsIntField | BoundsInt | 
| ColorField | 색상 | 
| CurveField | AnimationCurve | 
| FloatField | float | 
| GradientField | 그레디언트 | 
| IntegerField | int | 
| IntegerField | int, for the ArraySize | 
| LayerMaskField | unit | 
| ObjectField | UnityEngine.Object | 
| PopupField<string> | 열거형 | 
| RectField | Rect | 
| RectIntField | RecInt | 
| TextField | 문자열 | 
| TextField, with a maxLength=1 | char | 
| Toggle | bool | 
| Vector2Field | Vector2 | 
| Vector2IntField | Vector2Int | 
| Vector3Field | Vector3 | 
| Vector3IntField | Vector3Int | 
| Vector4Field | Vector4 |