Canvas 的立体 UI - MRTK3
注意
这是关于如何构建基于 Canvas 的混合 UI 的概念性概述。 有关单个 UX 预制件的文档,请参阅 UX 组件文档。
MRTK3 引入了与 Unity 的 RectTransform 和 Canvas 系统集成的立体 UI。 虽然此系统以前主要用于 2D 平面 UI,但它能够呈现立体 3D UI 并对其进行布局。 这可以加速设计迭代和提高可使用立体 UI 创建的设计的保真度。
注意
基于 Canvas 的组件库正在积极开发中,并且会随着新功能、外观、布局和体系结构而快速变化。
MRTK 2.x 的非 Canvas UI 系统很难设计,因为它们缺乏界面设计系统所需的许多基本功能。
- ✘ 缺少非物理设计单元
- ✘ 无对齐方式
- ✘ 无边距/填充
- ✘ 无灵活布局或响应式布局
- ✘ 布局、大小和配置的每一个排列都有不同的预制件
- ✘ 对集合布局(水平/垂直可组合布局)的支持非常有限
- ✘ 缺少基本设计功能,例如绝对大小的圆角弧度或笔划宽度
- ✘ 需要通过缩放来调整 UI 元素大小,这会破坏性地改变子级
- ✘ 对鼠标和键盘的支持有限
- ✘ 不支持手柄
由于这些限制,立体 UI 的设计一直更原始,需要技术设计师进行大量手工来创建漂亮的布局。
MRTK3 引入了一种统一的方法。 可以在 Canvas-RectTransform 上下文中创作支持所有 XR 交互(如铰接式手部跟踪按压和凝视-捏合)的精美立体 UI 控件。 可为控件自动布置适当的边距、填充、响应式弹性和设计师期望的所有功能。 此外,我们可以将 UGUI 事件向下路由到 XRI,使完全相同的 UI 预制件在 2D 上下文和 3D 上下文中同样有效,包括手柄等可访问的输入。
其优势包括:
- ✔ 映射到各种物理上下文(3D 现实、2D 屏幕、电视/桌面/移动设备/Web)的灵活设计单元
- ✔ 对于具有紧密联系的父/子关系的响应式布局的完整 RectTransform 对齐支持
- ✔ 通过 UnityUI AutoLayout 组提供完整的 RectTransform 边距和填充支持
- ✔ 通过 UnityUI AutoLayout 组支持具有优先级和边距的弹性布局
- ✔ 每种类型的控件都有一个预制件,可以对其重设大小和进行调整以适应任何内容或上下文
- ✔ UnityUI AutoLayout 组提供水平、垂直和网格布局。 可以通过扩展 Unity 布局界面自定义布局。
- ✔ 提供多种高级设计功能,如绝对大小的圆角弧度、笔划宽度和边距,由混合现实图形工具包中高级 UI 着色器功能提供支持。
- ✔ 无缩放:所有大小和布局都通过 RectTransform 大小和偏移指标实现。 父级不会缩放子级。
- ✔ 通过 UGUI 事件以及
UGUIInputAdapter
和CanvasProxyInteractor
完全支持鼠标 + 键盘(请参阅可交互体系结构文档了解详细信息) - ✔ 支持手柄和方向/相对导航
这种强大功能和灵活性是有代价的,需要仔细管理基于 Canvas 的 UI 以避免常见的性能缺陷。
- UI 的每个“移动部分”都应是不同的 Canvas 节点。 改变 Canvas 层次结构会产生
O(tree_height)
成本;强烈建议对多个移动部件/可重用组件使用多个画布。 - 避免对整个场景使用单个全局画布。
- 移动和旋转 Canvas 和 RectTransforms 可能会影响性能。 强烈建议将 Canvas 嵌套在要移动的非 RectTransform“套”转换下,而不是直接移动 Canvas。
- 我们关于屏蔽和剪裁基于碰撞体 UI 的情景仍在开发之中。 请考虑避免使用包含可点击内容的滚动视图。
- 默认 Unity 方向导航系统在某些 3D 上下文中可能会表现得很奇怪。 我们正在研究在独特 3D 布局中表现更可靠的自定义导航系统。
随着我们在一系列设备上执行更详细的性能测试,我们将发布更具体的指导来优化基于 Canvas 的布局。
安装
我们的组件是使用 1 个设计单元创作的:1 毫米的比例,用于物理上下文。 在设置 Canvas 以与立体 UI 配合使用时,专用于在沉浸式 3D 应用程序中显示:
- 确保 Canvas 设置为 worldspace 模式
- 确保 Canvas 的比例在所有轴上均为 0.001
对于在 2D 显示器上呈现的应用程序,可以自由调整比例,以匹配指定的可用性指标和最小触摸目标大小。
将可交互对象与 UGUIInputAdapter
一起使用时(例如我们基于 Canvas 的 UX),请确保场景中的 GameObject(最好是空的)上有一个 CanvasProxyInteractor
。 这将通过 XRI 转发 UGUI 事件,确保可交互对象正常工作。
如果要在非 UX 组件上试验 UGUI 输入,请将 UGUIInputAdapter
添加到XRI 可交互对象。 非 UX 相关的可交互对象上的 UGUI 输入是试验性的,并且存在几个未解决的 bug。
正在进行的开发
我们仍在打造开发场景,以便在我们支持的各种平台上构建精美的 UI。 目前,对于大多数 UX 组件,我们仍提供两个版本:一个版本不使用 Canvas,采用非响应式静态布局(正如我们过去在 MRTK 2.x 中提供的那样),另一个版本使用我们基于 Canvas 的统一方法构建。 随着我们构建更多组件并充实我们的设计库实现,我们期望我们将弃用非 Canvas 组件,以实现一致性和维护。
统一状态管理
由于状态/交互与视觉对象严格分离,你会注意到 Canvas 和非 Canvas 上下文共享相同状态和交互脚本。 这是设计使然;相同的交互脚本可以跨任何视觉对象或布局上下文重复使用,从而减少 API 图面并增强交互的一致性。 例如,Slider
同时是 Canvas 和非 Canvas 滑块的滑块交互组件,PressableButton
是跨 Canvas 和非 Canvas 按钮的相同脚本。 将来,如果采用新的布局或呈现框架,我们可以延续相同的交互逻辑和系统,以确保一致性和可维护性。
以下体系结构图详细说明了不同输入事件和可交互对象类型如何协同工作以提供统一的交互状态。 单击图表查看大图。