Version: Unity 6.0 (6000.0)
语言 : 中文
向 UXML 添加样式
引用 UXML 的其他文件

重用 UXML 文件

您可以将 UXML 文件创建为模板,并在其他 UXML 文件中重复使用。

导入 UXML 模板

设计大型用户界面时,可以创建定义 UI 部分的模板 UXML 文件,并使用 <Template><Instance> 元素将其导入另一个 UXML 文件。

例如,如果您有一个具有图像、名称和标签的纵向__ UI__(即用户界面,User Interface)让用户能够与您的应用程序进行交互。Unity 目前支持三种 UI 系统。更多信息
See in Glossary
元素,则可以创建一个 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 模板的实例时,您可以覆盖其元素的默认属性值。属性覆盖允许多次实例化同一模板,每个实例使用不同的值。

覆盖属性

您可以使用 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 的实例中的任何元素,并且

  • 用新值 Alice 覆盖其 text 属性的默认值。
  • 用新值 Tooltip 1 覆盖其 tooltip 属性的默认值。
<AttributeOverrides element-name="player-name-label" text="Alice" tooltip="Tooltip 1" />

嵌套属性覆盖

属性覆盖通过元素层级结构中的嵌套模板传播。例如,如果模板 A 实例化模板 B,而模板 B 实例化模板 C,则模板 A 和模板 B 都可以覆盖模板 C 中的属性。

当您覆盖嵌套模板中的属性时,最浅的覆盖优先。在上面的示例中,如果模板 A 和模板 B 都覆盖了模板 C 的相同属性,则模板 A 中的覆盖决定了呈现的 UI 中实际出现的内容。

覆盖模板实例样式

如果要创建 UXML 模板的实例,并且模板中的元素具有使用 style 属性定义的内联样式,则不能使用 AttributeOverrides 覆盖该 style 属性。但是,可以在 USS 样式表中使用 USS 选择器来覆盖模板实例的样式。

例如,如果您有以下名为 Hotkeys.uxml 的 UXML 模板,该模板定义了具有两个标签的 #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>

如果要创建两个模板实例,而第二个模板具有反向的灵活行方向,则不能使用 AttributeOverides 覆盖第二个实例中 #Container 元素的 style 属性。

要覆盖样式,请执行以下操作:

  • 删除上述 UXML 模板 (Hotkeys.uxml) 中的 #Container 样式。
  • 在 UXML 实例文件中,为两个实例命名,例如 HotkeysXMLReversedHotkeysXML
  • 将 USS 样式表(例如 ContextHotkeys.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;
}

限制

属性覆盖具有以下限制:

  • 属性覆盖根据您指定的元素名称查找匹配的属性。不能使用 USS 选择器UQuery 来匹配元素。
  • 尽管您可以覆盖元素的 binding-path 属性,但属性覆盖与数据绑定无关。
  • 无法覆盖元素的 classnamestyle 属性。

指定 UXML 模板中的子元素嵌套位置

您可以使用视觉元素的 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" ...>
    <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 属性提供任何值。

其他资源

向 UXML 添加样式
引用 UXML 的其他文件