版本:Unity 6 (6000.0)
语言:English
向 UXML 添加样式
从 UXML 引用其他文件

重用 UXML 文件

您可以创建一个 UXML 文件作为模板,并在其他 UXML 文件中重用它。

导入 UXML 模板

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

例如,如果您有一个包含图像、名称和标签的肖像UI(用户界面) 允许用户与您的应用程序交互。Unity 目前支持三种 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 模板的实例时,您可以覆盖其元素的默认属性值。属性覆盖允许您多次实例化相同的模板,并为每个实例使用不同的值。

覆盖属性

您可以使用 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 的同一个属性,则模板 A 中的覆盖将决定渲染的 UI 中实际显示的内容。

覆盖模板实例样式

如果您正在创建 UXML 模板的实例,并且模板中的某个元素使用 style 属性定义了内联样式,则无法使用 AttributeOverrides 来覆盖该 style 属性。但是,您可以使用 USS 样式表中的 USS 选择器来覆盖模板实例的样式。

例如,如果您有以下名为 Hotkeys.uxml 的 UXML 模板,它定义了一个带有两个标签的 #Container,并且 #Container 具有定义 flex 行方向的内联样式:

<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>

如果您想创建两个模板实例,其中第二个实例具有反向 flex 行方向,则无法使用 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 模板中嵌套子元素的位置

您可以使用视觉元素视觉树的一个节点,它实例化或派生自 C# VisualElement 类。您可以设置外观样式、定义行为并在屏幕上将其显示为 UI 的一部分。 更多信息
参见 术语表
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 引用其他文件