バインディングの目的は、オブジェクト内のプロパティを表示可能な UI に同期することです。バインディングとは、プロパティとそれを変更するビジュアルコントロールの間のリンク (紐づけ) を指します。
バインディングは、オブジェクトと、BindableElement から派生した UIElement、または IBindable インターフェースを実装した UIElement の間で行われます。
UnityEditor.UIElements
名前空間から
基本クラス
コントロール
UnityEngine.UIElements
名前空間から
基本クラス
コントロール
バインドは、上記の名前空間の 1 つからコントロールを使用する際に、以下の手順で行います。
以下のコードスニペットは 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)
{
// シリアル化オブジェクトを作成
SerializedObject so = new SerializedObject(selectedObject);
// 階層のルートにバインドします。それはバインドするのに適切なオブジェクトを見つけます。
rootVisualElement.Bind(so);
// ... または、他の方法として、それを TextField そのものにバインドすることもできます。
// m_ObjectNameBinding.Bind(so);
}
else
{
// 実際のビジュアル要素からオブジェクトのバインディングを破棄します
rootVisualElement.Unbind();
// m_ObjectNameBinding.Unbind();
// バインディングを破棄した後に TextField を消去します
m_ObjectNameBinding.value = "";
}
}
}
}
Unity で、Window > UIElementsExamples > Simple Binding Example を選択します。このウィンドウを使用してシーン内のゲームオブジェクトを選択し、表示された TextField でその名前を変更できます。
このセクションでは、UXML 階層の設定を通してバインディングの使用法を説明します。
UXML では、属性 binding-path
は TextField コントロールで定義されます。binding-path
が、コントロールをオブジェクトの実効プロパティにバインドします。
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)
{
// シリアル化オブジェクトを作成
SerializedObject so = new SerializedObject(selectedObject);
// 階層のルートにバインドします。それはバインドするのに適切なオブジェクトを見つけます...
rootVisualElement.Bind(so);
}
else
{
// 実際のビジュアル要素からオブジェクトのバインディングを破棄します
rootVisualElement.Unbind();
// バインディングを破棄した後に TextField を消去します
// (Q() が 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>
UXMLファイル tank_inspector_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);
}
USS ファイル tank_inspector_styles.uss
は、各要素のスタイルを定義します。
以下の表は、PropertyField でサポートされているフィールドの一覧です。各フィールドにはデータ型が含まれます。
フィールド | 型 |
---|---|
BoundsField | Bounds |
BoundsIntField | BoundsInt |
ColorField | Color |
CurveField | AnimationCurve |
FloatField | float |
GradientField | Gradient |
IntegerField | int |
IntegerField | int (ArraySize 用) |
LayerMaskField | unit |
ObjectField | UnityEngine.Object |
PopupField<string> | Enum |
RectField | Rect |
RectIntField | RecInt |
TextField | string |
TextField (maxLength=1) | char |
Toggle | bool |
Vector2Field | Vector2 |
Vector2IntField | Vector2Int |
Vector3Field | Vector3 |
Vector3IntField | Vector3Int |
Vector4Field | Vector4 |