视觉树保存窗口中的所有视觉元素。它是由称为视觉元素的轻量级节点组成的对象图。
这些节点在 C# 堆上分配(手动进行分配或通过从 UXML 模板文件加载 UXML 资源的方式进行分配)。
每个节点都包含布局信息、其绘制和重绘选项以及节点如何响应事件。
VisualElement
是视觉树中所有节点的公共基类。VisualElement
基类包含样式、布局数据、本地变换、事件处理程序等的属性。
VisualElement
有若干子类,包括专门的控件,它们定义了其他行为和功能。VisualElement
可包含子元素。
不需要从 VisualElement
基类进行派生来使用 UIElements。可以通过样式表和事件回调来自定义 VisualElement
的外观和行为。
视觉树的根对象称为面板。新元素在连接到面板之前将被忽略。可以向现有元素添加元素来将用户界面连接到面板。
为了验证 VisualElement
是否已连接到面板,可以测试此元素的 panel
属性。未连接视觉元素时,测试将返回 null
。
注意:UIElements 处于实验性阶段时,必须仔细查看 UnityEditor.Experimental.UIElements
命名空间中的扩展方法 GetRootVisualContainer()
。需要此命名空间来防止意外使用这一属性。
按以下顺序绘制视觉树中的元素:
更改绘制顺序的唯一方法是在父项中重新排序 VisualElement
对象。
可以在 RenderTexture
中绘制子树,并通过设置 VisualElement.clippingOptions = ClippingOptions.ClipAndCacheContents
将像素重新用于未来的重绘事件。
不同的坐标系定义如下:
布局系统会计算每个元素 VisualElement.layout
属性(Rect
类型)。
layout.position
表示为相对于其父项坐标空间的像素。虽然可以直接为 layout.position
赋值,但建议您使用样式表和布局系统来定位元素。
每个 VisualElement
也有一个 layout.transform
属性(ITransform
类型)可相对于父元素对元素进行定位。默认情况下,transform
是标识。
VisualElement.layout.position
和 VisualElement.layout.transform
属性用于定义如何在局部坐标系和父坐标系之间进行转换。
VisualElementExtensions
静态类提供了以下扩展方法在坐标系之间转换点和矩形:
WorldToLocal
将 Vector2
或 Rect
从 Panel
空间转换为元素内的参照。LocalToWorld
将 Vector2
或 Rect
转换为 Panel
空间参照。ChangeCoordinatesTo
将 Vector2
或 Rect
从一个元素的局部空间转换为另一个元素的局部空间。例如,在上图中,树的排列如下:
Panel
DockArea
并标记为“Coordinates”)
VisualElement
充当根(称为“root container”,即根容器)
VisualElement
充当按钮的父级(“red container”,即红色容器)
Button
从面板的角度来看:
position
属性(在 layout
属性中定义)设置为 (100, 100),因为它相对于它的父项:根容器。position
属性(在 layout
属性中定义)设置为 (0, 0),因为它相对于它的父项:红色容器。元素的原点是其左上角。
使用 worldBound
属性,同时考虑 VisualElement
的祖先的变换和位置,可以检索该元素的窗口空间坐标。