Version: 6000.3
语言: 中文
向UXML添加样式
从UXML引用其他文件

重用UXML文件

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

导入UXML模板

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

例如,如果你有一个具有图像、名称和标签的纵向UI元素,你可以将UXML模板文件创建为Portrait.uxml内容如下:

<ui:UXML xmlns:ui="UnityEngine.UIElements">
    <ui:VisualElement class="portrait">
        <ui:Image name="portraitImage" style="--unity-image: url(a.png)"/>
        <ui:Label name="nameLabel" text="Name"/>
        <ui:Label name="levelLabel" text="42"/>
    </ui:VisualElement>
</ui:UXML>

然后,您可以像这样重复使用肖像模板:

<ui:UXML xmlns:ui="UnityEngine.UIElements">
    <ui:Template src="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属性,您要覆盖其属性的元素
  • 要覆盖的属性的名称
  • 新属性值

例如,如果你想为游戏中的每个玩家显示同一组信息,你可以创建一个UXL模板,并使用属性覆盖来创建特定于玩家的实例。

首先,创建一个模板,例如PlayerTemplate.uxml,内容如下:

<ui:UXML xmlns:ui="UnityEngine.UIElements">
    <ui:Label name="player-name-label" text="default name" />
    <ui:Label name="player-score-label" text="default score" />
</ui:UXML>

然后,从另一个UXML文件实例化它,并覆盖其属性以显示每个玩家的姓名和分数:

<ui:UXML xmlns:ui="UnityEngine.UIElements">
    <ui:Template src="PlayerTemplate.uxml" name="PlayerTemplate" />
    <ui:Instance name="player1" template="PlayerTemplate">
        <!-- Alice is the new value of the text attribute for the player-name-label -->
        <ui:AttributeOverrides element-name="player-name-label" text="Alice" /> 
        <!-- 2 is the new value of the text attribute for the player-score-label -->
        <ui:AttributeOverrides element-name="player-score-label" text="2" />
    </ui:Instance>
    <ui:Instance name="player2" template="PlayerTemplate">
        <!-- Bob is the new value of the text attribute for the player-name-label -->
        <ui:AttributeOverrides element-name="player-name-label" text="Bob" />
        <!-- 1 is the new value of the text attribute for the player-score-label -->
        <ui:AttributeOverrides element-name="player-score-label" text="1" />
    </ui:Instance>
</ui:UXML>

覆盖多个属性

您可以为每个覆盖指定多个属性。例如,以下语法在名为player-name-label

  • 覆盖其text属性替换为新值,Alice.
  • 覆盖其tooltip属性替换为新值,Tooltip 1.
<ui: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定义#Container使用两个标签,并且#Container具有定义 flex 行方向的内联样式:

<ui:UXML xmlns:ui="UnityEngine.UIElements" >
    <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以覆盖style属性的#Container元素。

要覆盖样式,请先删除内联style属性#Container元素。内联样式优先于 USS 样式,因此删除它们可以应用 USS 规则。

接下来,在创建模板实例的UXML文件中,为每个实例分配唯一名称(例如,HotkeysReversedHotkeys).参考您的 USS 样式表(例如ContextHotKeys.uss) 在此文件中:

<ui:UXML xmlns:ui="UnityEngine.UIElements">
    <ui:Template name="Hotkeys" src="Hotkeys.uxml"/>
    <Style src="ContextHotKeys.uss"/>
    <ui:Instance template="Hotkeys" name="Hotkeys" />
    <ui:Instance template="Hotkeys" name="ReversedHotkeys" />
</ui:UXML>

然后,在样式表文件中ContextHotKeys.uss,您可以使用实例名称作为选择器来定位#Container元素。这使您可以根据需要将不同的样式应用于每个实例。

#ReversedHotkeys > #Container {
    flex-direction: row-reverse;
}

#Hotkeys > #Container {
    flex-direction: row;
}

局限性

属性覆盖具有以下限制:

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

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

您可以使用content-container属性视觉元素实例化或派生自 C# 的可视化树的节点VisualElement类。您可以设置外观样式、定义行为并将其作为 UI 的一部分显示在屏幕上。更多信息
请参阅术语表
以指定在UXML模板中嵌套子元素的位置。例如,如果你有以下UXML模板文件作为MyTemplate.uxml:

<ui:UXML xmlns:ui="UnityEngine.UIElements" >
    <ui:Label text="Group Title" name="groupTitle" />
    <ui:VisualElement name="parent-container" content-container="anyValue">
         <!--Add child elements here -->
    </ui:VisualElement>
    <ui:VisualElement />
</ui:UXML>

然后,您可以应用具有嵌套子元素的模板,如下所示:

<ui:UXML xmlns:ui="UnityEngine.UIElements">
    <ui:Template src="MyTemplate.uxml" name="my-template"/>
    <ui:Instance template="my-template">
        <ui:Label text="Test"/> <!--This label element is instantiated inside the `parent-container` element-->
    </ui:Instance>
</ui:UXML>

注意

  • 您可以向content-container属性。
  • 仅定义一个元素,其中包含content-container属性。如果多个元素具有此属性,则会给系统带来歧义。在这种情况下,子元素嵌套在第一个具有content-container属性在深度优先遍历可视化树轻量级节点组成的对象图,用于保存窗口或面板中的所有元素。它定义了使用 UI 工具包构建的每个 UI。
    请参阅术语表
    .为确保可预测的行为,只需定义content-container在模板中的单个元素上。

其他资源

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