UI 工具包包含一个布局引擎,根据布局和样式属性定位元素。布局引擎使用 Yoga 的布局原则,它实现了 Flexbox 的子集,一种 HTML/CSS 布局系统。 UI(用户界面) 允许用户与您的应用程序交互。Unity 目前支持三种 UI 系统。 更多信息
查看 词汇表 工具包属性与 Yoga 布局行为匹配。UI 工具包支持 Flexbox 中的大多数属性。
默认情况下,所有元素都是布局的一部分。布局具有以下默认行为
VisualElement
在其大小计算中使用文本大小。此行为可以由其他布局属性限制。UI 工具包包含针对标准 UI 组件(如按钮、切换按钮或文本字段)的内置 控件。这些内置控件具有影响其布局的样式。
以下是主要样式属性
flex-direction
):定义 主轴 的布局方向。默认值为 column
,这使得 主轴 从上到下运行。flex-grow
):定义元素应在 主轴 上如何增长。它是一个与同一父级的其他所有兄弟元素共享的比率。此属性在尝试使元素拉伸以占据其父级 (减去任何兄弟元素) 的整个大小时很有用。为此,将 Flex > 增长 值设置为 1
。如果您有两个兄弟元素,它们的 flex-grow
设置为 1
,那么它们将分别占用父级沿 主轴 的可用大小的 50%。align-items
):定义元素在 交叉轴 上的对齐方式,即与 主轴 垂直的轴。例如,如果您在 VisualElement
中有两个按钮,它们具有 flex-direction: column
和 align-items: flex-end
设置,那么这两个按钮将挤压到容器的右边缘。align-items
的选项名称类似于 flex-start
和 flex-end
,因为它们取决于 flex-direction
的值。justify-content
):定义元素在 主轴 上的对齐方式。例如,如果您在 VisualElement
中有两个按钮,它们具有 flex-direction: column
和 justify-content: flex-end
设置,那么这两个按钮将挤压到容器的底部边缘。justify-content
的选项名称类似于 flex-start
和 flex-end
,因为它们取决于 flex-direction
的值。有关更多信息,请参阅 Flex 布局。
如果所选元素具有子元素,则在 UI 生成器中,您可以使用标题中的切换按钮来切换 视口用户在屏幕上看到应用程序的可见区域。
查看 词汇表 中与 flex 相关的样式属性。下图显示了 #menu
元素的可用选项
您可以使用样式属性创建复杂的动态布局。以下是一个在屏幕右下角锚定 Button
的布局示例
此布局的 UXML 如下所示,显示了在每个容器 VisualElement
上设置的内联样式
<ui:UXML xmlns:ui="UnityEngine.UIElements" xmlns:uie="UnityEditor.UIElements">
<ui:VisualElement name="screen-is-blue" style="flex-grow: 1; justify-content: flex-end; background-color: blue;">
<ui:VisualElement name="toolbar-is-orange" style="align-items: flex-end; background-color: orange;">
<ui:Button text="Button" display-tooltip-when-elided="true" />
</ui:VisualElement>
</ui:VisualElement>
</ui:UXML>
这些容器被着色以显示其形状。您可以使用嵌套的 VisualElement
容器来实现任何动态布局,而无需显式设置每个元素的位置和大小。这使布局保持动态,并自动调整以适应较大的容器大小变化,例如屏幕大小变化。
UI 生成器还支持 位置 样式属性。位置 > 绝对 模式使元素对默认的基于 Flexbox 的布局引擎不可见。就好像它不再占用任何空间。绝对 定位的元素会出现在任何 相对 定位的兄弟元素之上。
在使用 绝对 定位时,您可以使用 位置 > 左、上、右、下 样式属性来从父级的相应边缘偏移和调整元素的大小。这不会在屏幕上设置绝对坐标,而是设置相对于父元素的偏移量。您仍然可以使用 相对 模式来定位父元素。如果您同时设置了 左 偏移量和 右 偏移量,则元素的 宽度 样式属性将被忽略,计算出的宽度将来自以下公式
element-computed-width = parent-width - left-offset - right-offset
左、上、右、下 也可以解释为锚点。例如,您可以将 Button
锚定到屏幕的左下角
以下 UXML 显示内联样式
<ui:UXML xmlns:ui="UnityEngine.UIElements" xmlns:uie="UnityEditor.UIElements" editor-extension-mode="False">
<ui:VisualElement style="flex-grow: 1;">
<ui:VisualElement style="position: absolute; left: 0; bottom: 0;" />
</ui:VisualElement>
</ui:UXML>
在定位方面,将 左 设置为 0
与未设置 左 之间存在差异
左设置为 0
表示设置偏移量为 0。左未设置
不会设置任何偏移量,并允许其他样式属性定义元素的宽度或高度。您也可以通过元素蓝色选择边框的每个边缘和角上的附加调整大小手柄,直接在 画布 中修改这些偏移样式属性。区分已设置和未设置的内容非常重要,因此 画布 还包括作为元素每一侧的橙色方块的“锚点”切换按钮。画布 手柄将根据设置的“锚点”调整视觉上调整元素大小时的设置样式属性。例如,假设您正在通过 画布 中的右侧边界手柄调整元素的大小
避免使用 绝对 定位模式,因为它会绕过 UI 工具包中的内置布局引擎,并可能导致高维护 UI,其中更改整体布局需要手动更新各个元素。但是,绝对 定位适合特定用例,例如覆盖层。在某些复杂 UI 之上覆盖一些复杂 UI(如弹出窗口或下拉列表)时,这非常有用。在这些情况下,对覆盖层容器使用 绝对 定位,但继续对覆盖层内部的元素使用 相对 模式以保持灵活性。
以下是简单居中弹出窗口的示例
以下是如何用 UXML 表示的
<ui:UXML xmlns:ui="UnityEngine.UIElements" xmlns:uie="UnityEditor.UIElements">
<ui:VisualElement name="complex-ui-screen">
<ui:Toggle label="Toggle" />
<ui:MinMaxSlider picking-mode="Ignore" label="Min/Max Slider" min-value="10" max-value="12" low-limit="-10" high-limit="40" />
<ui:Label text="Label" />
<ui:Button text="Button" />
<ui:Button text="Button" />
</ui:VisualElement>
<ui:VisualElement name="overlay" style="position: absolute; left: 0; top: 0; right: 0; bottom: 0; background-color: rgba(0, 0, 0, 0.71); align-items: center; justify-content: center;">
<ui:VisualElement name="popup" style="background-color: rgba(70, 70, 70, 255);">
<ui:Label text="Exit?" name="message" />
<ui:Button text="OK" name="ok-button" style="width: 108.3333px;" />
</ui:VisualElement>
</ui:VisualElement>
</ui:UXML>
上面的示例突出了 绝对 定位的使用。将所有 位置 > 左、上、右、下 设置为 0
,因此定位距离屏幕边缘 0
像素。这使得 #overlay
元素与 #complex-ui-screen
容器元素重叠。您还可以为 #overlay
元素设置半透明背景,以使其他 UI 显得变暗。使用 #overlay
来设置 相对 定位,以便将 #popup
容器 VisualElement
居中。
以下列表提供了一些提示,可以帮助提高布局引擎的性能
设置 width
和 height
来定义元素的大小。
使用 flexGrow
属性 (USS: flex-grow: <value>;
) 为元素分配灵活的大小。flexGrow
属性的值在元素由其兄弟元素决定大小时,为元素的大小分配一个基本权重。
将 flexDirection
属性设置为 row
(USS: flex-direction: row;
) 以切换到水平布局。
使用相对定位来根据元素的原始布局位置偏移元素。
将 position
属性设置为 absolute
以相对于其父级位置矩形放置元素。这不会影响其兄弟元素或父级的布局。