Unity3D :重用 UXML 文件

推荐:将NSDT场景编辑器加入你的3D工具链
3D工具集:NSDT简石数字孪生

重用 UXML 文件

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

导入用户体验模板

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

例如,如果您有肖像用户界面
元素,具有图像、名称和标签,您可以创建 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

  • 用新值 覆盖其属性的默认值。textAlice
  • 用新值 覆盖其属性的默认值。tooltipTooltip 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 模板的实例,并且模板中的元素具有使用该属性定义的内联样式,则不能用于覆盖该属性。但是,您可以在 USS 样式表中使用 USS 选择器来覆盖模板实例的样式。styleAttributeOverridesstyle

例如,如果您有以下名为 UXML 的模板,该模板定义了具有两个标签的 ,并且具有定义弹性行方向的内联样式:Hotkeys.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>

如果要创建两个模板实例,其中第二个模板实例具有反向的 flex 行方向,则不能在第二个实例中覆盖元素的属性。AttributeOveridesstyle#Container

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

  • 删除上述 UXML 模板 () 中的样式。#ContainerHotkeys.uxml
  • 在 UXML 实例文件中,将两个实例命名为“和”。HotkeysXMLReversedHotkeysXML
  • 将 USS 样式表(如 )应用于 UXML 实例文件。ContextHotkeys.uss
<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>

You can then apply the template with nested child elements as this:

<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

其他资源

  • 模板
  • 使用 UXML 实例作为模板

3D建模学习工作室整理翻译,转载请注明出处!

上一篇:Unity3D :向 UXML 添加样式 (mvrlink.com)

下一篇:Unity3D :从UXML引用其他文件 (mvrlink.com)

NSDT场景编辑器 | NSDT 数字孪生 | GLTF在线编辑器 | 3D模型在线转换 | UnrealSynth虚幻合成数据生成器 | 3D模型自动纹理化工具
2023 power by nsdt©鄂ICP备2023000829号