Version: 2023.2
言語: 日本語
カスタムコントロール
UXML のタグ名と属性のカスタマイズ

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

A good custom control is abstract, self-contained, and recurring.

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

  • 抽象化 (一般化) されています。ある設定と別の設定を切り替えるために使用します。
  • 自己完結的です。ユーザーはラベルと初期値を設定します。スライドトグルは、その状態が変化するとイベントをトリガーします。
  • 繰り返し登場します。アプリケーションの複数の場所で使用できます。

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

  • 抽象化 (一般化) されていません。そのアプリケーションに固有のものです。
  • It’s not self-contained. It probably has dependencies on other parts of your application.
  • 繰り返し登場しません。おそらく、アプリケーションにはメニューが 1 つしかありません。

After you have created a custom control, you can style it with USS and add logic to handle events in C#.

Create and use a custom control

To create a custom control, do the following:

  • Add the UxmlElement attribute to the custom control class definition.
  • Declare the custom control class as a partial class.
  • Inherit it from VisualElement or one of its derived classes.

例:

[!code-cs[(Modules/UIElements/Tests/UIElementsExamples/Assets/Examples/CreateCustomControl.cs)]

You can use your custom controls in UXML and UI Builder after you create them.

The following example UXML document uses the custom control:

[!code-cs[(Modules/UIElements/Tests/UIElementsExamples/Assets/Examples/CreateCustomControl.uxml)]

By default, the custom control appears in the Library tab in UI Builder. If you want to hide it from the Library tab, add the HideInInspector attribute.

カスタムコントロールを初期化する

カスタムコントロールは VisualElement から継承されます。VisualElement はゲームオブジェクトの生存期間には縛られず、以下のどのコールバックも受け取りません。

  • Awake()
  • OnEnable()
  • OnDisable()
  • OnDestroy()

You can initialize a custom control in its constructor. However, if your application needs it, you can delay initialization until the custom control is added to the UI. To do this, register a callback for an AttachToPanelEvent. To detect that your custom control has been removed from the UI, use the DetachFromPanelEvent callback.

public CustomControl()
{
    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 dispatches these two events for all elements and doesn’t need a custom VisualElement subclass. For more information, refer to Panel events.

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

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

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

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

CustomStyleProperty describes the name and type of property you read from the stylesheet.

UI Toolkit dispatches CustomStylesResolvedEvent for any element that directly receives a custom USS property. It dispatches the event for any element that a selector matches, for selectors where the rule contains the value of the custom property. UI Toolkit doesn’t dispatch the event for elements that inherit the value. The event holds a reference to an ICustomStyle object. You must use its TryGetValue() method to read the effective value of a CustomStyleProperty. This method has overloads for different types of CustomStyleProperty.

For a custom style with a custom control example, refer to Create custom style for a custom control.

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

Handle events for custom controls

For detailed information on how to handle events for custom controls, refer to Handle events.

ノート:

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

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

  • 任意のカスタムコントロールに対応するプロパティと、その動作のその他の機能的側面を、 UXML プロパティとして公開し、カスタムコントロールの見た目に影響を与えるプロパティを USS プロパティとして公開します。

  • 他の要素との名前の競合を避けるために、短くて読みやすい固有の名前空間を使用します。

  • Keep UXML attributes primitive. Data that you can specify in UXML is limited to a set of primitive data types. UXML doesn’t support complex data structures or collections. Pass complex data to your custom controls at runtime via C# scripts or data binding, not in UXML.

  • C# では、USS のクラスや名前を定数として公開します。これにより、UQuery を使用してクラスや名前によって要素を見つけることが可能になります。

  • USS クラスには BEM 規格 を使用します。これにより、全ての要素がクラスリストセレクターで扱えるようになります。

  • メモリフットプリントを小さくするために静的コールバックを使用します。コールバックとして使用するインスタンスメソッドを登録する時に、不要なアロケーションが発生することがあります。アロケーションを避けるには、通常の C# の静的メソッドを呼び出す匿名の静的ラムダ関数を使用します。EventBase.currentTarget プロパティで現在の要素のコンテキストを取得できます。

  • Render custom geometry through the generateVisualContent callback for custom controls. For an example usage that renders a partially filled circle, refer to the RadialProgress example.

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

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

その他の参考資料

カスタムコントロール
UXML のタグ名と属性のカスタマイズ