データ バインディングは、MonoBehaviour
の string
プロパティなどの非 UI オブジェクトのプロパティを、TextField の value
プロパティなどの UI オブジェクトのプロパティと同期します。バインディングは、プロパティとそれを変更するビジュアルコントロールの間のリンクを指します。
データバインディングを使用して、プロパティと特定のビジュアル要素との間で値を同期させます。そのため、UI で値が変更されたときに、イベントハンドラー を書く必要はありません。
ノート: SerializedObject のデータバインディングはエディターでだけ機能し、ランタイムには機能しません。
シリアル化されたプロパティ にのみバインドする (関連付ける、紐づける) ことができます。つまり、ビジュアル要素をバインドできるのは、シリアル化システム と互換性のある以下のオブジェクトに限られます。
ScriptableObject
クラスMonoBehaviour
クラスint
、bool
、float
などの C# のプリミティブ型Vector3
、Color
、Object
などの Unity のネイティブの型INotifyValueChanged
インターフェースを実装したビジュアル要素の value
プロパティのみをバインドすることができます。例えば、TextField.value
を string
(文字列) にバインドすることはできますが、TextField.name
を string
にバインドすることはできません。
BindableElement
から派生するか、IBindable
インターフェースを実装するオブジェクトと任意のビジュアル要素の間でバインドすることができ ます。
バインディングを作成するには、Bind()
または BindProperty()
のいずれかを呼び出します。
Bind()
を呼び出すBind()
を呼び出して、要素をSerializedObject にバインドすることができます。要素をバインドする前に,バインドパスを設定し SerializedObject を作成する必要があります.
バインディングの SerializedProperty
に簡単にアクセスできない場合は、このメソッドを使用します。例として、C# スクリプトでバインディングを作成する を参照してください。
Bind()
拡張メソッドは、指定された bindingPath
プロパティを持つビジュアル要素の階層全体を設定します。Bind()
メソッドを、単一の要素またはバインドしたい階層の親に対して呼び出すことができます。例えば、Bind()
をエディターウィンドウの rootVisualElement
上で呼び出すことができます。これにより、指定した bindingPath
プロパティを持つすべての子要素がバインドされます。
Bind()
を Editor.CreateInspectorGUI()
または PropertyDrawer.CreatePropertyGUI()
のオーバーライドから呼び出さないようにしてください。これらのオーバーライドは、これらのメソッドが返すビジュアル要素で自動的に呼び出されます。
Unbind()
を呼び出すUnbind()
メソッドは、要素とその直接および間接のすべての子要素の値の追跡を停止します。一般に、ユーザーが Inspector やエディターウィンドウを閉じるときに追跡が停止するため、Unbind()
を呼び出す必要はありません。Unbind()
は、要素の生存期間に異なるターゲットに要素をバインドする必要がある場合に呼び出します。
C# でコンストラクターを呼び出して InspectorElement
を構築する場合、 コンストラクター呼び出し時にバインドが発生します。InspectorElement
を構築した後でバインドし直す場合は、Unbind()
を呼び出し、`Bind() を明示的に呼び出すか、親からのバインド操作でバインディングを作成する必要があります。
Bind()
を呼び出してバインディングを作成する場合、ビジュアル要素のバインディングパスをバインドしたいオブジェクトのプロパティ名に設定する必要があります。
例:
以下のようなコンポーネントスクリプトがある場合
using UnityEngine;
public class MyComp : MonoBehaviour
{
[SerializeField]
int m_Count;
}
ビジュアル要素を m_Count
にバインドするには、バインドパスを m_Count
に設定します。
ビジュアル要素を、ゲームオブジェクトの name プロパティ (m_Name
) にバインドする場合は、バインドパスを m_Name
に設定します。
バインディングパスは、UI Builder、UXML、または C# スクリプトで設定することができます。
binding-path
属性を設定します。例として、UXML でのバインディングパスの定義 を参照してください。IBindable
インターフェースから bindingPath
を設定します。例として バインディングパスによるバインド を参照してください。BindProperty()
を呼び出すBindProperty()
を呼び出して、要素を SerializedProperty
に直接バインドすることができます。
SerializedProperty
オブジェクトをすでに持っている場合、特に SerializedObject
のプロパティを走査して動的に UI を構築する場合に、このメソッドを使用します。例として バインディングパスなしのバインド を参照してください。
ビジュアル要素をソースオブジェクトのネストされたプロパティにバインドすることができます。これを行うには、要素のバインディングパスと最初の先祖のバインディングパスを組み合わせます。この方法は、以下の要素で使用します。
BindableElement
TemplateContainer
(UXML の <Instance>
タグに対応)GroupBox
例として、ネスト状のプロパティにバインド を参照してください。
バインドされたシリアル化されたプロパティが変更されたときにコールバックを受け取るバインディングを作成することができます。そのためには、TrackPropertyValue()
拡張メソッドを活用します。このメソッドは、任意の VisualElement
で利用可能です。これは、提供された SerializedProperty
が変更されたときに実行するコールバックを登録します。例として、シリアル化されたプロパティが変更されたときにコールバックを受け取る を参照してください。
また、バインドされたシリアライズオブジェクトのいずれかのプロパティが変更されたときにコールバックを受信するバインディングを作成することもできます。そのためには、TrackSerializedObjectValue()
拡張メソッドを活用します。これは、任意の VisualElement
で利用可能です。これは、提供された SerializedProperty
が変更されたときに実行するコールバックを登録します。例として、プロパティが変更されたときにコールバックを受け取る を参照してください。
カスタム要素を作成し、値のバインディング システムを通じて、シリアル化されたプロパティにバインドすることができます。
バインド可能なカスタム要素を作成するには、以下を行います。
BindableElement
から要素を継承するか、IBinding
インターフェースを実装します。INotifyValueChanged
インターフェースを実装します。SetValueWithoutNotify()
メソッドを INotifyValueChanged
インターフェースに実装します。value
プロパティアクセサーを INotifyValueChanged
インターフェースに実装します。例として、カスタムコントロールの作成とスタイル設定 を参照してください。
When writing a custom inspectors you don’t have to explicitely bind a serialized object to the visual tree like in the editor windows examples above. This step is done implicitely after the CreateInspectorGUI
method finishes. This automatic binding step is only performed at that time. If you add a field outside of a callback to the CreateInspectorGUI
method, you will need to bind it manually. Otherwise it might fail to render or produce undefined visual results.
作成する UI の種類によって、バインドは様々なタイミングで発生します。これはバインド時間と呼ばれます。
以下の表では、操作の設定項目について説明します。
条件 | 自動バインド時間 (バインディングパスが設定されていることが前提) |
---|---|
C# で 構築される InspectorElement |
コンストラクター の呼び出し中 |
A child element that is under the return value of CreateInspectorGUI() or CreatePropertyGUI() when those methods return |
After CreateInspectorGUI() or CreatePropertyGUI() returns |
A child element that is under an element when Bind() or BindProperty() is called on the parent element |
During the Bind() or BindProperty() call |
Other | 自動バインディングはありません。要素またはその親の 1 つを手動でバインドする必要があります。 |
バインドタイムに関して、バインディングを作成する際のベストプラクティスを以下に示します。
Editor
or custom PropertyDrawer
, set the elements’ binding paths instead of calling Bind()
or BindProperty()
on any visual elements that are in the visual tree by the end of the body of CreateInspectorGUI()
or CreatePropertyGUI()
. These elements are bound automatically after CreateInspectorGUI()
or CreatePropertyGUI()
returns. However, if you add any elements to the visual tree after that point, call Bind()
or BindProperty()
to bind them.Bind()
or BindProperty()
regardless of the time at which the elements get added to the visual tree. If you call Bind()
or BindProperty()
and bind multiple controls at the same time, set the binding path of each control and then call Bind()
on the lowest-level parent element that encompasses all the controls. Bind()
binds the element on which it’s called if it has a binding path and recursively binds all its child elements if they have binding paths. To prevent a negative performance impact, don’t bind a visual element with the Bind()
method more than once.