テンプレートとして UXML ファイルを作成し、他の UXML ファイル内でそれを再利用できます。
大規模なユーザーインターフェースを設計する場合は、UI の部分部分を定義するテンプレート UXML ファイルを作成し、<Template>
および <Instance>
要素を使用して、それを別の UXML ファイルにインポートすることが可能です。
例えば、画像、名前、ラベルを持つポートレート UI 要素がある場合、以下の内容で、Assets/Portrait.uxml
として 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>
その上で、この Portrait テンプレートを以下のように再利用できます。
<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
属性例えば、ゲーム内の各プレイヤーに同じ一式の情報を表示したい場合は、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 の同じ属性をオーバーライドする場合、テンプレート B によるオーバーライドの方が、描画された UI に実際に何が表示されるかを決定します。
UXML テンプレートのインスタンスを作成していて、テンプレート内の要素に style
属性で定義されたインラインスタイルがある場合、その style
属性は、AttributeOverrides を
使用してオーバライドすることはできません。ただし、USS スタイルシート内で USS セレクターを使用することで、テンプレートインスタンスのスタイル設定をオーバーライドできます。
例えば、以下のように、Hotkeys.uxml
という 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 つ目のインスタンスの伸縮する行の方向を逆にしたい場合、AttributeOverides
を使用して 2 つ目のインスタンスの #Container
要素の style
属性をオーバーライドすることはできません。
スタイルをオーバーライドするには、以下のようにします。
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>
上記を行った上で、以下のように、ContextHotkeys.uss
を作成してテンプレートインスタンス名に応じて #Container
のスタイルを変更できます。
# ReversedHotkeysXML > #Container {
flex-direction: row-reverse;
}
# HotkeysXML > #Container {
flex-direction: row;
}
属性のオーバーライドには以下の制限があります。
binding-path
属性をオーバーライドすることはできますが、データバインディングは属性のオーバーライドには機能しません。class
属性や name
属性、style
属性はオーバーライドできません。ビジュアル要素の content-container
属性を使用して、UXML テンプレート内のどこに子要素をネストするか指定できます。例えば、以下の UXML テンプレートファイルが Assets/MyTemplate.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" ...>
<Template path="Assets/MyTemplate.uxml" name="my-template"/>
<ui:Instance template="my-template">
<ui:Label text="Test"/> <!--This label element will be instantiated inside the `group-container` element.-->
</ui:Instance>
<ui:Instance template="my-template">
<ui:Label text="Test"/> <!--This label element will be instantiated in the template -->
</ui:Instance>
</ui:UXML>
ノート: content-container
属性には任意の値を指定できます。