创建一个EditorWindow的UI ToolKit

当我们在项目中鼠标右键创建UI Toolkit

它会为我们自动创建一个C#脚本

VisualElement

VisualElement 是所有UI元素的基础类。它是UI Toolkit中最基本的构建块,用于创建和管理UI元素。

面板参数详解

1. View Data Key

  • 作用: 用于保存和恢复UI元素的状态(如滚动位置、折叠状态等)。

  • 用法: 当UI元素需要在不同的会话之间保持状态时,可以设置一个唯一的 View Data Key。Unity会根据这个键值自动保存和恢复元素的状态。

2. Picking Mode

  • 作用: 控制UI元素是否可以被鼠标或触摸事件选中。

  • 选项:

    • Position: 元素可以被选中,事件会根据元素的位置进行检测。

    • Ignore: 元素不会被选中,事件会穿透到下面的元素。

3. Tooltip

  • 作用: 当用户将鼠标悬停在元素上时显示的提示文本。

  • 用法: 设置一个字符串作为提示信息,帮助用户理解元素的用途。

4. Usage Hints

  • 作用: 提供关于元素使用方式的提示,帮助优化渲染性能。

  • 选项:

    • None: 无特殊提示。

    • DynamicTransform: 表示元素的变换(如位置、旋转、缩放)可能会频繁变化。

    • GroupTransform: 表示元素是一个组,其子元素的变换可能会频繁变化。

    • MaskContainer: 表示元素是一个遮罩容器,用于裁剪子元素。

5. Tab Index

  • 作用: 控制元素在Tab键导航顺序中的位置。

  • 用法: 设置一个整数值,决定元素在Tab键导航时的顺序。值越小,优先级越高。

6. Focusable

  • 作用: 控制元素是否可以获得焦点。

  • 用法: 如果设置为 true,元素可以通过Tab键或点击获得焦点,适合用于输入框、按钮等交互元素。

7. Class List

  • 作用: 允许为元素添加CSS类,以便应用样式。

  • 用法: 通过 AddToClassListRemoveFromClassList 方法动态添加或移除类。

8. Style

  • 作用: 允许直接设置元素的样式属性。

  • 用法: 通过 style 属性访问和修改元素的样式,如颜色、字体、边距等。

使用VisualElement作为一张图片

每一个VisualElement都有一个BackGround属性,我们可以设置颜色,背景图片等。在Image中就可以背景图片。

VisualTreeAsset

我的理解:它就是一个模板。通过 CloneTree() 方法生成对应的 VisualElement 树,用于动态创建UI。

Flex组件

Basis:就像给项目(比如一个盒子)规定了一个“初始占地面积”。

  • 默认值 auto:盒子大小根据内容自动调整(比如文字多就宽,图片大就大)。

  • 设置固定值:比如 100px,不管内容多少,盒子的初始宽度就是 100 像素。

Shrink:当空间不够时,决定哪个盒子“缩得更多”。

  • 数值越大,缩得越狠

    • 比如两个盒子,A 的 shrink: 1,B 的 shrink: 3

    • 空间不足时,B 会缩到只有 A 的三分之一大小(数值是比例关系)。

  • 默认值 1:所有盒子默认都能等比收缩。

Grow:当空间有剩余时,决定哪个盒子“占得更多”。

  • 数值越大,占得越多

    • 比如两个盒子,A 的 grow: 1,B 的 grow: 2

    • 剩余空间会被分成 3 份(1+2),A 占 1 份,B 占 2 份。

  • 默认值 0:默认不扩展(保持初始大小)。

Direction:决定盒子是“横着排”还是“竖着排”

  • row → 横着排(从左到右,像一行字)。

  • column → 竖着排(从上到下,像一列按钮)。

  • row-reverse → 反向横排(从右到左)。

  • column-reverse → 反向竖排(从下到上)。

Wrap:当一行放不下时,盒子是否“换行”

  • nowrap → 不换行(挤在一起,可能变形)。

  • wrap → 换行(从上到下另起一行)。

  • wrap-reverse → 反向换行(从下到上叠起来)

ScrollView组件

Picking Mode:是否能点击选中内容(比如设为None时,点列表没反应)

Tooltip:鼠标悬停时的提示文字(比如悬停在按钮上显示“点击使用”)

Focusable:能否被键盘或手柄选中(比如设为True,可以用方向键切换选项)。

Tab Index:用Tab键切换焦点的顺序(数值越小,越先被选中)

Horizontal/Vertical Scroller Visibility:设置为Auto后,内容溢出时滚动条才显示

Elastic Animation Interval Ms:弹性动画的刷新间隔(数值越小,动画越流畅)

Elasticity:设置为0.1后,滑动到列表顶部/底部时会有轻微弹性效果

ListView组件

ListView是一个用于显示可滚动列表的控件,通常用于展示动态生成的数据,比如物品列表、任务列表等。它支持数据绑定、虚拟化(仅渲染可见项以提高性能)以及自定义列表项的模板。

  • 数据驱动:通过 itemsSource 绑定数据集合(需实现 IList 接口)。

  • 模板化:通过 makeItem 定义列表项的视觉模板(基于 VisualTreeAsset)。

  • 动态绑定:通过 bindItem 将数据绑定到每个列表项。

  • 虚拟化:自动优化渲染,仅生成可见区域的列表项以提升性能

面板详解

数据交互

View Data Key:给列表绑定数据的“钥匙”(比如用 "PlayerInventory" 绑定背包数据),就像给抽屉贴标签,告诉 Unity “这个列表要显示抽屉里的东西”

Binding Path:直接绑定数据源的属性路径(比如绑定 ItemList.Name,列表会自动显示物品名称)

外观与布局

Fixed Item Height:设置为22,会强制每个列表项的高度固定为 22 像素(适合显示整齐的文本行)

Show Border:勾选后,显示列表边框(像 Excel 表格的外框)

Show Alternating Row Backgrounds:若设置为None,不显示交替行背景色(比如奇偶行颜色不同)。如果设为 ContentOnly:奇偶行会有轻微颜色区分,方便阅读。

交互行为

Selection Type:

  • 设置为Single只能单选(比如文件管理器中选择一个文件)。

  • 设置为None,不能选

  • 设置为Multiple,多选,按住 Ctrl 点击

Reorderable:勾选后,允许拖拽列表项重新排序(像手机桌面拖动图标换位置)

  • 如果Reorder Mode = Simple:直接拖拽交换位置(无动画)

Horizontal Scrolling:勾选后,允许横向滚动(比如列表项内容过长时,可以左右滑动查看)

功能扩展

Show Foldout Header:勾选后,显示可折叠的标题栏(像文件管理器的“详细信息”栏)

  • Header Title :在标题栏显示自定义文字(比如“任务列表”)

Show Add Remove Footer:勾选后,在列表底部显示“添加/删除”按钮(方便动态增删数据)

性能优化

Virtualization Method=Fixed Height:只渲染当前可见的列表项,大幅提升性能(适合超长列表)。

  • 原理:如果列表有 1000 项,但屏幕只能显示 10 项,Unity 只会创建 10 个元素,滑动时复用

其他参数

Picking Mode = Ignore:无视鼠标点击(列表项无法被选中或交互)

Focusable:勾选后,允许用键盘方向键或手柄切换焦点(比如在游戏菜单中用方向键选择选项)

  • Tab Index = 0:按 Tab 键时,焦点切换的顺序(数值越小越优先)

Tooltip:鼠标悬停时显示的提示文字(比如悬停在列表项上显示“双击查看详情”)

代码示例

// itemRowTemplate 是一个 UIDocument 模板文件
Func<VisualElement> makeItem = () => itemRowTemplate.CloneTree();
Action<VisualElement, int> bindItem = (ve, i) =>
{
    if (i < items.Count)
    {
        if (items[i].itemIcon != null)
            ve.Q<VisualElement>("Icon").style.backgroundImage = items[i].itemIcon.texture;
        ve.Q<Label>("Name").text = items[i] == null ? "No item" : items[i].name;
    }
};
// 设置列表项高度(需与UXML中样式一致)
itemListView.fixedItemHeight = 60;

// 通过 itemsSource 绑定数据集合
itemListView.itemsSource = items;

// 通过 makeItem 定义列表项的视觉模板(基于 VisualTreeAsset)
itemListView.makeItem = makeItem;

// 通过 bindItem 将数据绑定到每个列表项
itemListView.bindItem = bindItem;

UI Doc

UIDocument 是一个用于将UI Toolkit的UI界面与Unity场景或游戏对象关联的组件。它是UI Toolkit的核心组件之一,负责将UI文档(UXML文件)和样式表(USS文件)加载并渲染到Unity的场景中。

UI ToolKit Sample

我们可以在顶部菜单栏 Window > UI ToolKit > Sample中找到,里面提供了各种各样的C#、USS、UXML代码示例。我们可以在这里面去学习。