UXML 模板是使用 XML 标记编写的文本文件,用于定义用户界面的逻辑结构。以下代码示例演示了如何定义一个提示用户做出选择的简单面板:
<?xml version="1.0" encoding="utf-8"?>
<UXML
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="UnityEngine.UIElements"
xsi:noNamespaceSchemaLocation="../UIElementsSchema/UIElements.xsd"
xsi:schemaLocation="UnityEngine.UIElements ../UIElementsSchema/UnityEngine.UIElements.xsd">
<Label text="Select something to remove from your suitcase:"/>
<Box>
<Toggle name="boots" label="Boots" value="false" />
<Toggle name="helmet" label="Helmet" value="false" />
<Toggle name="cloak" label="Cloak of invisibility" value="false"/>
</Box>
<Box>
<Button name="cancel" text="Cancel" />
<Button name="ok" text="OK" />
</Box>
</UXML>
文件的第一行是 XML 声明。此声明为可选项。如果包含此声明,它必须在第一行,并且在它之前不能出现其他内容或空格。version
属性是必需属性。encoding
属性是可选属性。如果包含 encoding
,它必须声明文件的字符编码。
下一行定义文档根 <UXML>
。<UXML>
元素包含命名空间前缀定义的属性和架构定义文件的位置。可以按任意顺序指定这些属性。
在 UI 工具包中,每个元素都在 UnityEngine.UIElements
或 UnityEditor.UIElements
命名空间中定义:
UnityEngine.UIElements
命名空间包含被定义为 Unity Runtime 一部分的元素。UnityEditor.UIElements
命名空间包含 Unity Editor 中可用的元素。要完整指定一个元素,必须在其前面添加其命名空间。例如,如果要在 UXML 模板中使用 Button
元素,则必须指定 <UnityEngine.UIElements:Button />
。
要方便指定命名空间,可以定义命名空间前缀。例如,xmlns:engine="UnityEngine.UIElements"
将 engine
前缀定义为 UnityEngine.UIElements
。定义命名空间前缀之后,可以将其用于指定命名空间。例如,<engine:Button />
等同于 <UnityEngine.UIElements:Button />
还可以通过排除前缀来定义默认命名空间。例如,xmlns="UnityEngine.UIElements"
将 UnityEngine.UIElements
定义为默认命名空间。这意味着指定 <Button />
等同于 <UnityEngine.UIElements:Button />
如果是自行定义元素,这些元素可能在其自身的命名空间中定义。如果要在 UXML 模板中使用这些元素,则必须在 <UXML>
标签中包含命名空间定义和架构文件位置以及 Unity 命名空间。
通过选择 Asset > Create > UI Toolkit > Editor Window 来新建 UXML 模板资源时,编辑器自动为您定义命名空间。
UI 的定义在 <UXML>
根中。UI 定义是一系列嵌套的 XML 元素,每个元素代表一个 VisualElement
。
元素名称对应于要实例化的元素的 C# 类名。大多数元素都有属性,且属性的值映射到 C# 中相应的类属性。每个元素都继承其父类类型的属性,并可在父类类型的基础上添加自己的属性集。VisualElement
作为所有元素的基类,为所有元素提供以下属性:
name
:元素的标识符。名称应具有唯一性。picking-mode
:设置为 Position
(响应鼠标事件)或 Ignore
(忽略鼠标事件)。focus-index
:(已弃用)使用 tabIndex
和 focusable
。tabindex
:一个整数,定义当前元素的 Tab 键移动位置。focusable
:一个布尔值,指示是否可聚焦该元素。class
:用于表征元素的标识符的空格分隔列表。使用类为元素指定视觉样式。还可以使用类在 UQuery 中选择一组元素。tooltip
:鼠标悬停在元素上方时显示为工具提示的字符串。view-data-key
:一个字符串,可定义用于元素序列化的键。UXML 模板示例未定义用户界面的视觉要素。建议您使用单独的 USS 文件来定义用于绘制 UI 的样式信息,例如尺寸、字体和颜色(请参阅样式和 Unity 样式表)。
要引用样式表文件,UXML 文件可以在任何元素声明下使用 <Style>
元素。
例如,如果您在同一文件夹中有一个 UXML 文件以及一个名为 “styles.uss” 的 USS 文件:
<engine:UXML ...>
<engine:VisualElement class="root">
<Style src="styles.uss" />
</engine:VisualElement>
</engine:UXML>
# root {
width: 200px;
height: 200px;
background-color: red;
}
注意:Unity 不支持根 <UXML>
元素下的 <Style>
元素。
还可以直接将内联样式声明为 UXML 元素的属性:
<engine:UXML ...>
<engine:VisualElement style="width: 200px; height: 200px; background-color: red;" />
</engine:UXML>
可通过在 UXML 文件中定义组件的方式来创建组件,
并使用另一个 UXML 文件中的 <Template>
和 <Instance>
元素将组件导入。
在设计大型用户界面时,可以创建一些用于定义 UI 组成部分的模板 UXML 文件。
可能会在许多地方使用相同的 UI 定义。例如,假设有一个包含图像、名称和标签的纵向 UI 元素。可以创建一个 UXML 模板文件以便在其他 UXML 文件中重用此纵向 UI 元素。
例如,假设在 Assets/Portrait.uxml
文件中有一个 Portrait 组件:
<engine:UXML ...>
<engine:VisualElement class="portrait">
<engine:Image name="portaitImage" style="--unity-image: url(\"a.png\")"/>
<engine:Label name="nameLabel" text="Name"/>
<engine:Label name="levelLabel" text="42"/>
</engine:VisualElement>
</engine:UXML>
可以将 Portrait 组件嵌入到其他 UXML 模板中,如下所示:
<engine:UXML ...>
<engine:Template src="/Assets/Portrait.uxml" name="Portrait"/>
<engine:VisualElement name="players">
<engine:Instance template="Portrait" name="player1"/>
<engine:Instance template="Portrait" name="player2"/>
</engine:VisualElement>
</engine:UXML>
创建 UXML 模板的实例时,您可以覆盖其元素的默认属性值。属性覆盖允许多次实例化同一模板,每个实例使用不同的值。
要覆盖属性,您必须指定:
element-name 属性
在下面的示例中,
player-name-label
是元素的 element-name
属性。text
是要覆盖的属性。Alice
是新属性值<AttributeOverrides element-name="player-name-label" text="Alice" />
属性覆盖会影响整个实例,因此如果实例有两个名为 player-name-label
的元素,并且都具有 text
属性,则覆盖会对二者都有影响。
假设您正在制作一款游戏,并且希望为每个玩家显示相同的信息集。您可以创建一个可重用的模板,并使用属性覆盖来创建特定于玩家的实例。
例如,如果您创建以下模板:
<UXML xmlns="UnityEngine.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">
<AttributeOverrides element-name="player-name-label" text="Alice" />
<AttributeOverrides element-name="player-score-label" text="2" />
</Instance>
<Instance name="player2" template="MyTemplate">
<AttributeOverrides element-name="player-name-label" text="Bob" />
<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 的相同属性,则模板 B 中的覆盖决定了呈现的 UI 中实际出现的内容。
binding-path
属性。name
或 style
属性。UXML 文件可以通过元素引用其他 UXML 文件和 USS 文件。
<Template>
和 <Style>
元素都接受“src”属性或“path”属性。
src
属性允许相对路径,在导入时(例如,文件丢失时)提供错误消息,并确保 Unity 在播放器构建中正确包含 UXML 文件引用的资源。
path
属性允许使用 Unity 资源机制,但在导入时不提供错误报告,并且不允许使用相对路径。
src
属性src
属性要求文件路径相对于项目根目录或包含 UXML 文件的文件夹。必须包含文件扩展名。在以下示例中,UXML 文件位于 Assets\Editor\UXML 中,USS 文件位于 Assets\Editor\USS 中。
src="../USS/styles.uss"
或 src="template.uxml"
src="/Assets/Editor/USS/styles.uss"
或 src="project:/Assets/Editor/UXML/template.uxml"
。path
属性path
属性接受位于 Resources 文件夹或 Editor Default Resources 文件夹中的文件,并遵循以下规则:
path="template"
。path="template.uxml"
。Did you find this page useful? Please give it a rating:
Thanks for rating this page!
What kind of problem would you like to report?
Thanks for letting us know! This page has been marked for review based on your feedback.
If you have time, you can provide more information to help us fix the problem faster.
Provide more information
You've told us this page needs code samples. If you'd like to help us further, you could provide a code sample, or tell us about what kind of code sample you'd like to see:
You've told us there are code samples on this page which don't work. If you know how to fix it, or have something better we could use instead, please let us know:
You've told us there is information missing from this page. Please tell us more about what's missing:
You've told us there is incorrect information on this page. If you know what we should change to make it correct, please tell us:
You've told us this page has unclear or confusing information. Please tell us more about what you found unclear or confusing, or let us know how we could make it clearer:
You've told us there is a spelling or grammar error on this page. Please tell us what's wrong:
You've told us this page has a problem. Please tell us more about what's wrong:
Thank you for helping to make the Unity documentation better!
Your feedback has been submitted as a ticket for our documentation team to review.
We are not able to reply to every ticket submitted.