Version: 2021.3
言語: 日本語
コントロールリファレンス
スライドトグルカスタムコントロールの作成

カスタムコントロール

UI Toolkit allows you to create custom controls. This makes it possible to create complex controls, or implement custom logic for user interface elements. A good custom control is abstract, self-contained, and recurring.

スライドトグル は、優れたカスタムコントロールの例です。これには以下のような特徴があります。

  • It’s abstract: you use it to switch between one setting and another.
  • It’s self-contained: you provide it with a label and an initial value; it triggers an event when its state changes.
  • It’s recurring: you can use it in multiple places within an application.

アプリケーションのメニューバーは、優れたカスタムコントロールの例ではありません。これは以下のような特徴があります。

  • It’s not abstract: it’s specific to your application.
  • It’s not self-contained: it probably has dependencies to other parts of your application.
  • It’s not recurring: there is probably only one menu in your application.

After you have created a custom control, you can style it with USS, create logic to handle events, and use it in UI Builder.

カスタムコントロールの作成

カスタムコントロールを作成するには、カスタムコントロールの C# クラスを作成し、それを初期化する必要があります。これは UXML や UI Builder で使用できるように公開できます。また、データにバインドすることも可能です。

Create a custom control class

VisualElement クラスから派生する、あるいは VisualElement クラスのサブクラスから派生する、C# クラスを作成します。例えば、BindableElement の代わりに BaseField ジェネリック基本クラスから派生する、バインド可能なカスタムコントロールを作成できます。これには以下のような利点があります。

  • 指定したジェネリック型パラメーターの INotifyValueChanged インターフェースを実装します。
  • デフォルトでコントロールがフォーカス可能になります。
  • 左側にラベル要素、右側に入力を配置した、水平レイアウトを提供します。
FloatField は、BaseField から継承される、UI Toolkit のビルトインコントロールです。<br/>A. ラベル要素<br/>B. 入力要素
FloatField は、BaseField から継承される、UI Toolkit のビルトインコントロールです。
A. ラベル要素
B. 入力要素

ノート: ビルトイン UI コントロールから派生するカスタムコントロールを作成することも、その内部階層と既存の USS クラスに関する理解があれば可能です。この方法で作成したカスタムコントロールは、将来変更される可能性のある内部構造に依存してしまう場合があるため、Unity では、これを行うことは推奨していません。

Initialize a custom control

Custom controls inherit from VisualElement. A VisualElement is not bound to the lifetime of a GameObject and it does not receive Awake(), OnEnable(), OnDisable(), or OnDestroy() callbacks.

カスタムコントロールは、そのコンストラクター内で初期化できます。ただし、アプリケーションに必要であれば、カスタムコントロールが UI に追加されるまで初期化を遅らせることができます。これを行うには、AttachToPanelEvent のコールバックを登録します。カスタムコントロールが UI から削除されたことを検出するには DetachFromPanelEvent コールバックを使用します。

void OnEnable()
{
    var myCustomElement = rootVisualElement.Q(className: "my-custom-element");
    myCustomElement.RegisterCallback<AttachToPanelEvent>(e =>
        { /* do something here when element is added to UI */ });
    myCustomElement.RegisterCallback<DetachFromPanelEvent>(e =>
        { /* do something here when element is removed from UI */ });
}

UI Toolkit はこれら 2 つのイベントを全ての要素に対してディスパッチし、カスタムの VisualElement サブクラスを必要としません。詳細は パネルイベント を参照してください。

Expose custom controls to UXML and UI Builder

To use your custom controls with UXML and UI Builder, you must expose them. To do so, define a factory class derived from UxmlFactory<T> as described in Define new elements.

You can add new attributes to a custom control for use in UXML. To do this, define a traits class derived from UxmlTraits and override the Init() method as described in Define attributes on elements. The UI Builder relies on this to ensure that the visual element created for the Viewport updates when you change the value of a UXML property in the Inspector.

UI Builder の Inspector でカスタムコントロールの UXML プロパティを使用するには、UXML と C# スクリプトでプロパティ名を一致させる必要があります。UXML では標準のケバブケース表記を使用し、C# ではキャメルケースまたはパスカルケースを使用します。例えば、C# で MyFloat あるいは myFloat という名前のプロパティは、UXML では my-float となります。

Note: You can’t create logic in your C# script to detect whether a visual element is in the UI Builder preview mode. Therefore, Unity recommends you to design your custom control to be self-contained without side effects that you’d need to disable inside the UI Builder. For more information about the UI Builder’s Preview Mode, see Testing inside the UI Builder.

Bind custom controls to data

シリアル化されたプロパティにカスタムコントロールをバインドすることで、コントロールとプロパティの間で値を同期させます。

カスタムコントロールをデータに バインド するには、以下を行います。

詳細は SerializedObject のデータバインディング を参照してください。

バインド可能なカスタムコントロールの例は、バインド可能なカスタムコントロールの作成 で参照できます。

USS でのカスタムコントロールのスタイル設定

カスタムコントロールの見た目をカスタマイズするには、ビルトインコントロールの場合と同様に、USS を使用します。また、USS のカスタムプロパティ を作成してカスタムコントロールのスタイルを設定することもできます。

ノート: UI Builder の Inspector ウィンドウには、USS のカスタムプロパティは表示されません。USS のカスタムプロパティを編集するには、テキストエディターを使って USS ファイルを直接編集してください。

C# でカスタムコントロールのカスタム USS プロパティを操作するには、CustomStyleProperty 構造体と CustomStylesResolvedEvent イベントを使用します。

CustomStyleProperty は、スタイルシートから読み取ったプロパティの名前とタイプを記述します。

UI Toolkit は、カスタム USS プロパティを直接受け取る要素に対して CustomStylesResolvedEvent をディスパッチします。セレクターと一致する要素に対して、(セレクターの規則にカスタムプロパティの値が含まれる場合に) イベントがディスパッチされます。UI Toolkit は、値を継承する要素にはイベントをディスパッチしません。このイベントは ICustomStyle オブジェクトへの参照を持ちます。その TryGetValue() メソッドを使用して CustomStyleProperty の有効値を読み取る必要があります。このメソッドには、各種の CustomStyleProperty のオーバーロードがあります。

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

ノート: カスタムスタイルプロパティに遷移を定義することはできません。

カスタムコントロールのイベントの処理

カスタムコントロールのイベント処理方法に関する詳細は、イベントの処理 を参照してください。

ノート:

  • Unity は、現在フォーカスされている要素にキーボードイベントをディスパッチします。カスタムコントロールの キーボードイベント を処理するには、focus に関連するプロパティを設定します。
  • タッチやマウスの入力イベントを処理するには、適したイベントタイプ (ポインターイベントマウスイベント など) のコールバックをコンストラクター内で登録します。

UI Builder でのカスタムコントロールの使用

UI Builder でビジュアルツリーにカスタムコントロールを追加するには、以下を行います。

  1. Library > Project > Custom Controls (C#) を選択します。
  2. カスタムコントロールを Hierarchy ウィンドウにドラッグします。

ベストプラクティスとヒント

ベストプラクティス:

  • 任意のカスタムコントロールに対応するプロパティと、その動作のその他の機能的側面を、 UXML プロパティとして公開し、カスタムコントロールの見た目に影響を与えるプロパティを USS プロパティとして公開します。
  • 他の要素との名前の競合を避けるために、短くて読みやすい固有の名前空間を使用します。
  • UXML の属性はプリミティブにします。UXML で指定できるデータは、プリミティブ型データの集合に限られます。UXML は複雑なデータ構造やコレクションをサポートしていません。複雑なデータは、UXML ではなく C# スクリプトまたはデータバインディングによって、ランタイムにカスタムコントロールに渡します。
  • C# では、USS のクラスや名前を定数として公開します。これにより、UQuery を使用してクラスや名前によって要素を見つけることが可能になります。
  • USS クラスには BEM 規格 を使用します。これにより、全ての要素がクラスリストセレクターで扱えるようになります。
  • メモリフットプリントを小さくするために静的コールバックを使用します。コールバックとして使用するインスタンスメソッドを登録する時に、不要なアロケーションが発生することがあります。アロケーションを避けるには、通常の C# の静的メソッドを呼び出す匿名の静的ラムダ関数を使用します。EventBase.currentTarget プロパティで現在の要素のコンテキストを取得できます。

ヒント:

  • カスタムコントロールの generateVisualContent コールバックを使用してカスタムジオメトリをレンダリングします。部分的に塗りつぶされた円をレンダリングする使用例を、RadialProgress で参照できます。

  • カスタムコントロールは便利ですが、以下の方法でも同じ結果が得られる場合があります。

    • 既存の要素から UI を組み立て、そのスタイルやプロパティを変更します。
    • UXML テンプレートを使用します。通常の C# の MonoBehaviour を使用して、UI を保持する特定の UI ドキュメントに関連するロジックを追加します。(MonoBehaviour を使用して UI ドキュメントの UI を制御する方法については、ランタイム UI の作成に関するドキュメント を参照してください。) カプセル化を行うには、UQuery を使用して VisualElement を内部的にフェッチしてそれらのプロパティを操作するプロパティとメソッドを、MonoBehaviour 内に作成します。

その他の参考資料

コントロールリファレンス
スライドトグルカスタムコントロールの作成