Version: 2020.3
The UI Toolkit Package
布局引擎

视觉树

视觉树保存窗口中的所有视觉元素。它是由称为视觉元素的轻量级节点组成的对象图。

这些节点在 C# 堆上分配(手动进行分配或通过从 UXML 模板文件加载 UXML 资源的方式进行分配)。

每个节点都包含布局信息、其绘制和重绘选项以及节点如何响应事件。

VisualElement

VisualElement 是视觉树中所有节点的公共基类。VisualElement 基类包含样式、布局数据、本地变换、事件处理程序等的属性。

VisualElement 有若干子类,包括专门的控件,它们定义了其他行为和功能。VisualElement 可包含子元素。

You are not required to derive from the VisualElement base class to work with elements. You can customize the look and behavior of a VisualElement through stylesheets and event callbacks.

连接

视觉树的根对象称为面板。新元素在连接到面板之前将被忽略。可以向现有元素添加元素来将用户界面连接到面板。

为了验证 VisualElement 是否已连接到面板,可以测试此元素的 panel 属性。未连接视觉元素时,测试将返回 null

可在 UnityEditor.UIElements 命名空间中使用容器对象的 rootVisualElement 元素将新元素添加到树中。

绘制顺序

按以下顺序绘制视觉树中的元素:

  • 先绘制父项,再绘制子项
  • 根据同级名单绘制子项

更改绘制顺序的唯一方法是在父项中重新排序 VisualElement 对象。

位置、变换和坐标系

不同的坐标系定义如下:

  • 世界坐标系:坐标相对于面板空间。面板是视觉树中的最高层级元素。
  • 局部坐标系:坐标相对于元素本身。

布局系统会计算每个元素 VisualElement.layout 属性(Rect 类型)。

layout.position 表示为相对于其父项坐标空间的像素。虽然可以直接为 layout.position 赋值,但建议您使用样式表和布局系统来定位元素。

每个 VisualElement 也有一个 layout.transform 属性(ITransform 类型)可相对于父元素对元素进行定位。默认情况下,transform 是标识。

VisualElement.layout.positionVisualElement.layout.transform 属性用于定义如何在局部坐标系和父坐标系之间进行转换。

VisualElementExtensions 静态类提供了以下扩展方法在坐标系之间转换点和矩形:

  • WorldToLocalVector2RectPanel 空间转换为元素内的参照。
  • LocalToWorldVector2Rect 转换为 Panel 空间参照。
  • ChangeCoordinatesToVector2Rect 从一个元素的局部空间转换为另一个元素的局部空间。
视觉树层级视图
视觉树层级视图

例如,在上图中,树的排列如下:

  • Panel
    • 标签部分(称为 DockArea 并标记为“Coordinates”)
    • 蓝色 VisualElement 充当根(称为“rootVisualContainer”)
      • 红色 VisualElement 充当按钮的父级(“red container”,即红色容器)
        • Button

从面板的角度来看:

  • 无论参照如何,面板的原点都是 (0, 0)
  • 根的原点在世界空间中为 (0, 22)
  • 红色容器的原点在世界空间中为 (100, 122)。它的 position 属性(在 layout 属性中定义)设置为 (100, 100),因为它相对于它的父项:根容器。
  • 按钮的原点在世界空间中为 (100, 122)。它的 position 属性(在 layout 属性中定义)设置为 (0, 0),因为它相对于它的父项:红色容器。

元素的原点是其左上角。

使用 worldBound 属性,同时考虑 VisualElement 的祖先的变换和位置,可以检索该元素的窗口空间坐标。


  • 2018–11–02 页面已修订
The UI Toolkit Package
布局引擎