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.
スライドトグル は、優れたカスタムコントロールの例です。これには以下のような特徴があります。
アプリケーションのメニューバーは、優れたカスタムコントロールの例ではありません。これは以下のような特徴があります。
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 で使用できるように公開できます。また、データにバインドすることも可能です。
VisualElement
クラスから派生する、あるいは VisualElement
クラスのサブクラスから派生する、C# クラスを作成します。例えば、BindableElement
の代わりに BaseField
ジェネリック基本クラスから派生する、バインド可能なカスタムコントロールを作成できます。これには以下のような利点があります。
INotifyValueChanged
インターフェースを実装します。ノート: ビルトイン UI コントロールから派生するカスタムコントロールを作成することも、その内部階層と既存の USS クラスに関する理解があれば可能です。この方法で作成したカスタムコントロールは、将来変更される可能性のある内部構造に依存してしまう場合があるため、Unity では、これを行うことは推奨していません。
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
サブクラスを必要としません。詳細は パネルイベント を参照してください。
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.
シリアル化されたプロパティにカスタムコントロールをバインドすることで、コントロールとプロパティの間で値を同期させます。
カスタムコントロールをデータに バインド するには、以下を行います。
INotifyValueChanged
インターフェースを実装し、必要に応じて ChangeEvent
をリッスンします。BindableElement
クラスを継承するか、IBindable
インターフェースを実装します。詳細は SerializedObject のデータバインディング を参照してください。
バインド可能なカスタムコントロールの例は、バインド可能なカスタムコントロールの作成 で参照できます。
カスタムコントロールの見た目をカスタマイズするには、ビルトインコントロールの場合と同様に、USS を使用します。また、USS のカスタムプロパティ を作成してカスタムコントロールのスタイルを設定することもできます。
ノート: UI Builder の Inspector ウィンドウには、USS のカスタムプロパティは表示されません。USS のカスタムプロパティを編集するには、テキストエディターを使って USS ファイルを直接編集してください。
C# でカスタムコントロールのカスタム USS プロパティを操作するには、CustomStyleProperty
構造体と CustomStylesResolvedEvent
イベントを使用します。
CustomStyleProperty
は、スタイルシートから読み取ったプロパティの名前とタイプを記述します。
UI Toolkit は、カスタム USS プロパティを直接受け取る要素に対して CustomStylesResolvedEvent
をディスパッチします。セレクターと一致する要素に対して、(セレクターの規則にカスタムプロパティの値が含まれる場合に) イベントがディスパッチされます。UI Toolkit は、値を継承する要素にはイベントをディスパッチしません。このイベントは ICustomStyle
オブジェクトへの参照を持ちます。その TryGetValue()
メソッドを使用して CustomStyleProperty
の有効値を読み取る必要があります。このメソッドには、各種の CustomStyleProperty
のオーバーロードがあります。
カスタムコントロールの例を用いたカスタムスタイルについては、カスタムコントロールのカスタムスタイルを作成する を参照してください。
ノート: カスタムスタイルプロパティに遷移を定義することはできません。
カスタムコントロールのイベント処理方法に関する詳細は、イベントの処理 を参照してください。
ノート:
focus
に関連するプロパティを設定します。UI Builder でビジュアルツリーにカスタムコントロールを追加するには、以下を行います。
ベストプラクティス:
EventBase.currentTarget
プロパティで現在の要素のコンテキストを取得できます。ヒント:
カスタムコントロールの generateVisualContent
コールバックを使用してカスタムジオメトリをレンダリングします。部分的に塗りつぶされた円をレンダリングする使用例を、RadialProgress で参照できます。
カスタムコントロールは便利ですが、以下の方法でも同じ結果が得られる場合があります。
MonoBehaviour
を使用して、UI を保持する特定の UI ドキュメントに関連するロジックを追加します。(MonoBehaviour
を使用して UI ドキュメントの UI を制御する方法については、ランタイム UI の作成に関するドキュメント を参照してください。) カプセル化を行うには、UQuery を使用して VisualElement
を内部的にフェッチしてそれらのプロパティを操作するプロパティとメソッドを、MonoBehaviour
内に作成します。