UXML と UI Builder でカスタムコントロールを使用するには、それらを公開する必要があります。
新しい要素を定義するには、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 つの目的があります。
UxmlTraits
を使って、新しく作られたオブジェクトを初期化します。UxmlTraits
は分析され、要素に関する情報が取得されます。この情報は XML スキーマディレクティブに変換されます。上のサンプルコードは以下の処理を行います。
m_Status
の宣言は XML 属性 status
を定義します。uxmlChildElementsDescription
は StatusBar
要素に子がないことを示す空の 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> |
Enum 型 T 値の 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>
要素の属性として名前空間プレフィックスの定義を加えます。xsi:schemaLocation
属性に名前空間のスキーマファイルの場所を含めます。テキストエディターで新しい要素を確実に認識するには、Assets > Update UXML Schema を選択してスキーマ定義を更新します。
接頭辞付きの新しい UXML ドキュメントを作成するには、Assets > Create > UI Toolkit > UI Document を選択します。