Version: Unity 6.0 (6000.0)
言語 : 日本語
SerializedObject のデータバインディング
バインド可能な要素のリファレンス

SerializedObject データバインディングの概要

SerializedObject データバインディングシステムを使用して、シリアル化プロパティ にバインドすることができます。つまり、シリアル化システム と互換性のある以下のオブジェクトにビジュアル要素をバインドできます。

  • ユーザー定義の ScriptableObject クラス
  • ユーザー定義の MonoBehaviour クラス
  • Unity のネイティブのコンポーネントタイプ
  • Unity のネイティブのアセットタイプ
  • プリミティブな C# 型 (intboolfloat など)
  • ネイティブの Unity タイプ (Vector3ColorObject など)

値のバインディング

バインドできるのは、INotifyValueChanged インターフェースを実装するビジュアル要素の value プロパティだけです。例えば、TextField.valuestring にバインドすることはできますが、TextField.namestring にバインドすることはできません。

BindableElement から派生したビジュアル要素や、IBindable インターフェースを実装するビジュアル要素と、オブジェクトをバインドできます。

# ラグドールの作成

バインディングを作成するには、Bind() または BindProperty() を呼び出します。

Bind() を呼び出します。

Bind() を呼び出して、要素を SerializedObject にバインドできます。要素をバインドする前に、バインディングパスを設定 して、SerializedObject を作成する必要があります。

バインドする SerializedProperty に簡単にアクセスできない場合は、このメソッドを使用します。例については、C# スクリプトでバインディングを作成する を参照してください。

Bind() 拡張メソッドは、指定された bindingPath プロパティを使用してビジュアル要素の階層全体を設定します。バインドする 1 つの要素または階層の親で、Bind() メソッドを呼び出すことができます。例えば、Editor ウィンドウの rootVisualElementBind() を呼び出すことができます。この場合は、指定された bindingPath プロパティを使用してすべての子要素がバインドされます。

Editor.CreateInspectorGUI() または PropertyDrawer.CreatePropertyGUI() オーバーライドから Bind() を呼び出さないでください。これらのオーバーライドは、これらのメソッドから戻されるビジュアル要素で自動的に呼び出されます。

Unbind() を呼び出します。

Unbind() メソッドは、要素とその直接および間接のすべての子要素の値の追跡を停止します。通常では、ユーザーが Inspector や Editor ウィンドウを閉じるときに追跡が停止するため、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# スクリプトで設定することができます。

BindProperty() を呼び出します。

BindProperty() を呼び出して、要素を SerializedProperty に直接バインドすることができます。

このメソッドは、すでに SerializedProperty オブジェクトがある場合、特に SerializedObject のプロパティを走査して UI を動的にビルドする場合に使用します。例については、バインディングパスなしでバインドする を参照してください。

ネストされたプロパティに要素をバインドする

ビジュアル要素をソースオブジェクトのネストされたプロパティにバインドすることができます。それには、要素のバインディングパスと最初の先祖のバインディングパスを組み合わせます。この方法は、以下の要素で使用します。

例については、ネスト状のプロパティにバインドする を参照してください。

値が変更されたときにコールバックを受け取る

バインドされたシリアル化プロパティの変更時にコールバックを受信するバインディングを作成できます。それには、VisualElement に使用可能な TrackPropertyValue() 拡張メソッドを活用します。指定された SerializedProperty の変更時に実行されるコールバックをこれで登録します。例については、シリアル化プロパティが変更されたときにコールバックを受信する を参照してください。

バインドされたシリアル化オブジェクトのプロパティ変更時にコールバックを受信するバインディングを作成することもできます。それには、VisualElement に使用可能な TrackSerializedObjectValue() 拡張メソッドを活用します。指定された SerializedProperty の変更時に実行されるコールバックをこれで登録します。例については、プロパティが変更されたときにコールバックを受信する を参照してください。

カスタムエレメントをバインドする

カスタム要素を作成して、値のバインディング システムでシリアル化プロパティにバインドすることができます。

バインド可能なカスタム要素を作成するには、以下を行います。

  1. カスタム要素を宣言 します。
  2. 要素を BindableElement から継承するか、IBinding インターフェースを実装します。
  3. INotifyValueChanged インターフェースを実装します。
  4. SetValueWithoutNotify() メソッドを INotifyValueChanged インターフェースに実装します。
  5. value プロパティアクセサーを INotifyValueChanged インターフェースに実装します。

例については、カスタムコントロールの作成とスタイル設定 を参照してください。

ノート: バインディングシステムでは、enum の SerializedPropertyType でサポートされている型にしか要素をバインドできないため、カスタムデータ型をカスタム要素に直接バインドすることはできません。つまり、クラスや構造体 (例えば MyStruct という構造体) を定義してから、INotifyValueChanged<MyStruct> を実装する要素にそれをバインドすることはできません。ただし、シリアル化可能でネストされているカスタムデータ型プロパティにはバインドできます。これはポリモーフィックシリアル化 (フィールドで [SerializeReference] 属性を使用する場合) を含みます。例については、カスタムコントロールをカスタムデータ型にバインドする を参照してください。

推奨ガイド

作成する UI の種類によって、バインディングは様々なタイミングで発生します。これはバインド時間と呼ばれます。

以下の表では、操作の設定項目について説明します。

条件 自動バインド時間 (バインディングパスが設定されていることが前提)
C# で作成された InspectorElement コンストラクター の呼び出し中
これらのメソッドから戻された CreateInspectorGUI() または CreatePropertyGUI() の戻り値の下にある子要素 CreateInspectorGUI() または CreatePropertyGUI() が戻った後
親要素での Bind() または BindProperty() の呼び出し時に、要素の下にある子要素 Bind() または BindProperty() の呼び出し中
その他 自動バインディングはありません。要素またはその親の 1 つを手動でバインドする必要があります。

バインドタイムに関して、バインディングを作成する際のベストプラクティスを以下に示します。

  • カスタム Editor またはカスタム PropertyDrawer を作成する場合は、CreateInspectorGUI() または CreatePropertyGUI() のボディの終了までに ビジュアルツリー のビジュアル要素で Bind() または BindProperty() を呼び出す代わりに、その要素のバインディングパスを設定します。これらの要素は、CreateInspectorGUI() または CreatePropertyGUI() が戻った後に自動的にバインドされます。ただし、それ以降にビジュアルツリーに要素を追加するには、Bind() または BindProperty() を呼び出してバインドします。
  • それ以外の種類の UI を作成する場合は、要素がビジュアルツリーに追加されるタイミングに関係なく、Bind() または BindProperty() を呼び出します。Bind() または BindProperty() の呼び出しと、複数のコントロールのバインディングを同時に行う場合は、各コントロールのバインディングパスを設定してから、すべてのコントロールを含む最下位の親要素で、Bind() を呼び出します。Bind() は、呼び出された先でバインディングパスがある要素をバインディングし、バインディングパスがあるすべての子要素を再帰的にバインディングします。パフォーマンスへの悪影響を防ぐために、Bind() メソッドでビジュアル要素を複数回バインディングしないでください。

バインディングの例

データバインディングを使ったコード作成を学ぶには、以下の例を参照してください。

追加リソース

SerializedObject のデータバインディング
バインド可能な要素のリファレンス