UXML ファイルをテンプレートとして作成し、他の UXML ファイルで再利用できます。
大規模なユーザーインターフェースを設計する場合は、UI の一部を定義するテンプレート UXML ファイルを作成し、その <Template> と <Instance> 要素を使用して別の UXML ファイルにインポートできます。
例えば、画像、名前、ラベルを持つ縦向きの UI 要素がある場合、以下のコンテンツを含む UXML テンプレートファイルを Assets/Portrait.uxml として作成できます。
<ui:UXML ...>
<ui:VisualElement class="portrait">
<ui:Image name="portaitImage" style="--unity-image: url(\"a.png\")"/>
<ui:Label name="nameLabel" text="Name"/>
<ui:Label name="levelLabel" text="42"/>
</ui:VisualElement>
</ui:UXML>
縦向きのテンプレートは、次のように再利用できます。
<ui:UXML ...>
<ui:Template src="/Assets/Portrait.uxml" name="Portrait"/>
<ui:VisualElement name="players">
<ui:Instance template="Portrait" name="player1"/>
<ui:Instance template="Portrait" name="player2"/>
</ui:VisualElement>
</ui:UXML>
UXML テンプレートのインスタンスを作成して、その要素のデフォルト属性値をオーバーライドすることができます。属性のオーバーライドで、インスタンスごとに異なる値を使って同じテンプレートを何度もインスタンス化できます。
属性は UXML タグでオーバーライドできます。属性をオーバーライドするには、以下を指定します。
element-name
例えば、ゲームで各プレイヤーに同じ情報を表示するには、1 つの UXML テンプレートを作成し、属性のオーバーライドによってプレイヤー固有のインスタンスを作成できます。
まず、以下のコンテンツを含む MyTemplate.uxml というテンプレートを作成します。
<UXML xmlns="Unityui.UIElements">
<Label name="player-name-label" text="default name" />
<Label name="player-score-label" text="default score" />
</UXML>
次に、別の UXML ファイルからインスタンスを作成し、その属性をオーバーライドして各プレイヤーの名前とスコアを表示します。
<UXML xmlns="UnityEngine.UIElements" xmlns:uie="UnityEditor.UIElements">
<Template src="MyTemplate.uxml" name="MyTemplate" />
<Instance name="player1" template="MyTemplate">
<!-- Alice is the new value of the text attribute for the player-name-label -->
<AttributeOverrides element-name="player-name-label" text="Alice" />
<!-- 2 is the new value of the text attribute for the player-score-label -->
<AttributeOverrides element-name="player-score-label" text="2" />
</Instance>
<Instance name="player2" template="MyTemplate">
<!-- Bob is the new value of the text attribute for the player-name-label -->
<AttributeOverrides element-name="player-name-label" text="Bob" />
<!-- 1 is the new value of the text attribute for the player-score-label -->
<AttributeOverrides element-name="player-score-label" text="1" />
</Instance>
</UXML>
各オーバーライドで複数の属性を指定できます。例えば、以下の構文は、インスタンス内で player-name-label という名前の要素を検出します。
text 属性のデフォルト値を新しい値 Alice でオーバーライドします。tooltip 属性のデフォルト値を新しい値 Tooltip 1 でオーバーライドします。<AttributeOverrides element-name="player-name-label" text="Alice" tooltip="Tooltip 1" />
属性のオーバーライドは、要素階層のネスト状のテンプレートによって伝播します。例えば、テンプレート A がテンプレート B をインスタンス化し、テンプレート B がテンプレート C をインスタンス化する場合、テンプレート A とテンプレート B の両方がテンプレート C の属性をオーバーライドできます。
ネスト状のテンプレートの属性をオーバーライドする場合、最も浅い位置のオーバーライドが優先されます。したがって、上記の例では、テンプレート A とテンプレート B の両方がテンプレート C の同じ属性をオーバーライドする場合、レンダリングされる UI に何が実際に表示されるのかはテンプレート A のオーバーライドによって決まります。
UXML テンプレートのインスタンスを作成し、テンプレート内の要素に style 属性で定義されたインラインスタイルがある場合、AttributeOverrides を使用してその style 属性をオーバーライドすることはできません。ただし、USS スタイルシートで USS セレクターを使用して、テンプレートインスタンスのスタイルをオーバーライドできます。
例えば、以下の UXML テンプレート Hotkeys.uxml には、2 つのラベルを持つ #Container が定義され、#Container にはフレックス行の向きを定義するインラインスタイルがあります。
<ui:UXML xmlns:ui="UnityEngine.UIElements" xmlns:uie="UnityEditor.UIElements" editor-extension-mode="False">
<ui:VisualElement name="Container" style="flex-direction: row;">
<ui:Label text="E" name="Hotkeys" />
<ui:Label text="Talk" name="Action" />
</ui:VisualElement>
</ui:UXML>
2 つのテンプレートインスタンスを作成し、2 つ目のインスタンスではフレックス行を逆向きにする場合は、2 つ目のインスタンスの #Container 要素の style 属性をオーバーライドするのに、AttributeOverides を使用することはできません。
このスタイルをオーバーライドするには、以下の手順に従います。
Hotkeys.uxml) で #Container のスタイルを削除します。HotkeysXML や ReversedHotkeysXML などの名前を付けます。ContextHotkeys.uss などの USS スタイルシートを UXML インスタンスファイルに適用します。<ui:UXML xmlns:ui="UnityEngine.UIElements" xmlns:uie="UnityEditor.UIElements">
<ui:Template name="HotkeysXML" src="HotkeysXML.uxml"/>
<Style src="ContextHotKeys.uss"/>
<ui:Instance template="HotkeysXML" name="HotkeysXML" />
<ui:Instance template="HotkeysXML" name="ReversedHotkeysXML" />
</ui:UXML>
テンプレートインスタンス名に応じて #Container スタイルを変更する ContextHotkeys.uss を作成します。
#ReversedHotkeysXML > #Container {
flex-direction: row-reverse;
}
#HotkeysXML > #Container {
flex-direction: row;
}
属性のオーバーライドには以下の制限があります。
binding-path 属性をオーバーライドすることはできますが、データバインディングは属性のオーバーライドに使用できません。class、name、または style 属性はオーバーライドできません。ビジュアル要素の content-container 属性を使用して、UXML テンプレートの子要素のネスト場所を指定できます。例えば、Assets/MyTemplate.uxml という以下の UXML テンプレートがあるとします。
<ui:UXML xmlns:ui="UnityEngine.UIElements" ...>
<ui:Label text="Group Title" name="groupTitle" />
<ui:VisualElement name="group-container" content-container="anyValue">
<!--Add child elements here -->
</ui:VisualElement>
<ui:VisualElement />
</ui:UXML>
ネストされた子要素を持つテンプレートを次のように適用できます。
<ui:UXML xmlns:ui="UnityEngine.UIElements" ...>
<ui:Template path="Assets/MyTemplate.uxml" name="my-template"/>
<ui:Instance template="my-template">
<ui:Label text="Test"/> <!--This label element is instantiated inside the `group-container` element-->
</ui:Instance>
</ui:UXML>
ノート: content-container 属性には任意の値を指定できます。