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

カスタムコントロールを UXML と UI Builder に公開する

UXML と UI Builder でカスタムコントロールを使用するには、それらを公開する必要があります。

Factory を定義する

新しい要素を定義するには、VisualElement またはそのサブクラスの 1 つから新しいクラスを派生させ、この新しいクラスで適切な機能を実装します。

新しいクラスは、例えば以下のようなデフォルトのコンストラクターを実装する必要があります。

class StatusBar : VisualElement
{
    public StatusBar()
    {
        m_Status = String.Empty;
    }

    string m_Status;
    public string status { get; set; }
}

UXML ファイルを読み込むときに UI Toolkit が新しいクラスをインスタンス化できるようにするには、クラスの Factory を定義する必要があります。Factory が特別なことを行う必要がない限り、UxmlFactory<T> から Factory を派生させることができます。その Factory クラスをコンポーネントクラス内に配置することが推奨されます。

例えば、以下のコードスニペットでは、StatusBarクラスに対してUxmlFactory という名前の Factory を定義します。

class StatusBar : VisualElement
{
    public new class UxmlFactory : UxmlFactory<StatusBar> {}

    // ...
}

この Factory を定義すると、UXML ファイルの <StatusBar> 要素を使用することができます。

要素に属性を定義する

新しいクラスに UXML の特性 (traits) を定義し、その特性を使用するように Factory を設定することができます。

例えば、下のコードスニペットは UXML の Traits クラスを定義して status プロパティーを StatusBar クラスのプロパティーとして初期化する方法を示しています。status プロパティーは UXML データから初期化されます。

class StatusBar : VisualElement
{
    public new class UxmlFactory : UxmlFactory<StatusBar, UxmlTraits> {}

    public new class UxmlTraits : VisualElement.UxmlTraits
    {
        UxmlStringAttributeDescription m_Status = new UxmlStringAttributeDescription { name = "status" };

        public override IEnumerable<UxmlChildElementDescription> uxmlChildElementsDescription
        {
            get { yield break; }
        }

        public override void Init(VisualElement ve, IUxmlAttributes bag, CreationContext cc)
        {
            base.Init(ve, bag, cc);
            ((StatusBar)ve).status = m_Status.GetValueFromBag(bag, cc);
        }
    }

    // ...
}

UxmlTraits には 2 つの目的があります。

  • Factory は UxmlTraits を使って、新しく作られたオブジェクトを初期化します。
  • スキーマ生成処理によって UxmlTraits は分析され、要素に関する情報が取得されます。この情報は XML スキーマディレクティブに変換されます。

上のサンプルコードは以下の処理を行います。

  • m_Status の宣言は XML 属性 status を定義します。
  • uxmlChildElementsDescriptionStatusBar 要素に子がないことを示す空の IEnumerable を返します。
  • Init() メンバーは、XML パーサーからプロパティバッグの status 属性の値を読み込み、StatusBar.status プロパティにこの値に設定します。
  • UxmlTraits クラスは StatusBar クラスの中に置かれます。これにより、Init() メソッドが StatusBar のプライベートメンバーにアクセスできるようになります。
  • 新しい UxmlTraits クラスは基本クラス UxmlTraits を継承しているので、基本クラスの属性を共有します。
  • Init()base.Init() を呼び出して基本クラスのプロパティを初期化します。

前述のコード例は UxmlStringAttributeDescription クラスで文字列属性を宣言しています。UI Toolkit は以下のタイプの属性をサポートし、それぞれが C# 型を XML 型にリンクします。

属性 属性値
UxmlStringAttributeDescription 文字列
UxmlFloatAttributeDescription C# float 型の範囲の単精度浮動小数点値
UxmlDoubleAttributeDescription C# double 型の範囲の倍精度浮動小数点値
UxmlIntAttributeDescription C# int 型の範囲の整数値
UxmlLongAttributeDescription C# long 型の範囲の整数値
UxmlBoolAttributeDescription true または false
UxmlColorAttributeDescription USS 形式で定義された色を表す文字列
UxmlEnumAttributeDescription<T> EnumT 値の 1 つを表す文字列
UxmlTypeAttributeDescription<T> 型のアセンブリ修飾名を表す文字列
UxmlAssetAttributeDescription<T> A string that represents an asset.

上記のコード例では、uxmlChildElementsDescription は、StatusBar 要素が XML スキーマへの子要素の説明を受け入れないことを示す空の IEnumerable を返します。

要素が任意の型の子を受け入れるには、uxmlChildElementsDescription プロパティーをオーバーライドする必要があります。例えば、StatusBar 要素が任意の型の子を受け入れるためには、uxmlChildElementsDescription プロパティーを以下のように指定する必要があります。

public override IEnumerable<UxmlChildElementDescription> uxmlChildElementsDescription
{
    get
    {
        yield return new UxmlChildElementDescription(typeof(VisualElement));
    }
}

名前空間プレフィックスを定義する

C# で新しい要素を定義したら、その要素を UXML ファイルで使用できます。要素を分類するには、名前空間にクラスを作成します。新しい名前空間を定義するときに、その名前空間のプレフィックスを定義できます。名前空間プレフィックスをルート <UXML> 要素の属性として定義し、要素のスコープを設定するときに完全な名前空間名を置き換える必要があります。

名前空間プレフィックスを定義するには、それぞれの名前空間プレフィックスのアセンブリに 例えば以下のような UxmlNamespacePrefix 属性を加えます。

[assembly:UxmlNamespacePrefix( "My.First.Namespace"、 "first")]
[assembly:UxmlNamespacePrefix( "My.Second.Namespace"、 "second")]

これは、アセンブリの C# ファイルのルートレベル (任意の名前空間の外側) で行います。

スキーマ生成システムは以下を行います。

  • これらの属性を確認し、それらを使用してスキーマを生成します。
  • 新しく作成された UXML ファイルの <UXML> 要素の属性として名前空間プレフィックスの定義を加えます。
  • xsi:schemaLocation 属性に名前空間のスキーマファイルの場所を含めます。

テキストエディターで新しい要素を確実に認識するには、Assets > Update UXML Schema を選択してスキーマ定義を更新します。

接頭辞付きの新しい UXML ドキュメントを作成するには、Assets > Create > UI Toolkit > UI Document を選択します。

その他の参考資料

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