研发实战:微软分享如何基于MRTK3构建3D UI交互系统
Mixed Reality Toolkit(MRTK)
(映维网Nweon 2022年09月26日)微软的开源项目Mixed Reality Toolkit(MRTK)旨在帮助开发者轻松利用Unity开发跨平台MR应用,它同时允许开发者通过编辑器模拟轻松进行原型设计,并立即查看相应的改动。
这个MRTK提供了丰富的组件,用于手和眼追踪、输入、解算器、诊断工具、场景管理等的组件可以帮助你用更少的时间来搭载更出色的体验。通过MRTK构建的体验可以兼容任何支持OpenXR运行时的设备,例如HoloLens和Meta Quest。
对于全新的MRKT3,开发者届时可以选择更轻量级的解决方案。它允许你仅选择所需工具包的组件,而且提供了一个新的交互系统、新的主题和数据绑定功能、Unity画布支持,以及更新的设计语言。另外,本机OpenXR支持更容易定位多个设备,如HoloLens、Meta Quest、Windows Mixed Reality和未来支持OpenXR的设备。
日前,微软的芬恩·辛克莱尔(Finn Sinclair)撰文介绍了构建MRTK3的体三维UI。下面是映维网的具体整理:
MRTK3代表着我们MRT用户界面设计工具成熟度方面向前迈出的重要一步。在过去的一年里,我们投入了大量资源来现代化混合现实中的UI设计系统,并对组件库和工具进行了全面优化调整。如果你曾经有过MRTK的经验,你就会知道为混合现实应用构建漂亮的现代用户界面从来都不是一件容易的事情。高质量的体三维UI需要独特的工具和系统。从人员挑战(可用性和保持大型设计团队的一致性等等)到工程挑战(布局引擎、3D体三维交互、模拟输入、渲染/着色器),我们在开发更成熟的设计系统的过程中遇到并克服了几类UI工具挑战。
在MRTK3的下一代UI工具中,我们寻求通过更强大的工程系统来显著改善开发人员的体验,通过更现代的设计功能改善设计师的体验,并通过更令人愉快和身临其境的微交互和设计语言改善用户体验。
1. 爆炸的变体
在MRTK的早期版本中,设计3D UI通常意味着手动计算、对齐和填充的数学基础,以及众多无法响应布局或尺寸变化的手动放置asset。这种限制大多是由于MRTK2中构建UI的主要方式没有使用Unity可用的典型UI工具。后来的MRTK2版本探索了使用画布和RectTransform布局来构建3D UI,但它从来不是在MRTK中构建UI的首选/主要方式。
在微软,随着我们为MR设备构建了更大、更雄心勃勃的应用,我们已经达到了需要更多现代设计工具、工作流程和方法来管理高度复杂UI布局的规模。当你有100多名工程师、设计师和项目经理时,保持设计语言和布局的一致性是一个重大挑战。如果我们依然在使用手动方法来对齐、调整大小和设计UI,我们很快就会碰到一堵巨大的墙壁,而上面会有数百个略微错位的按钮、毫米级的问题、成倍增长的预置变体和asset数量。这真是一场噩梦。
过去,MRTK的第三方用户可能经历过这个问题的小型版本,特别是从描述UI控件的所有可能配置和大小所需的大量预置和预置变体。我们有一个指数级的变种,我们需要为按钮样式、配置、布局甚至“大小”的每一种排列提供变种(最后一个特别令人沮丧)。
有了MRTK3,我们大大减少了预制件的数量。我们可以使用单个预置,而不需要预置变量来调整大小和配置,允许用户自由调整控件的大小,在控件中添加和删除自己的子功能,甚至用动态布局展开按钮组/列表/菜单。
你在MRTK3中通常使用的每个按钮都是相同的预置式按钮。所有UI元素都是可调整大小,可以动态适应其周围的容器及其内容。这都不是真正的MRTK特定发明。我们只是确保我们所有的用户体验都是按照Unity自己的用户界面所构建的相同标准进行构建,并且兼容所有现有的布局组、约束和对齐系统。
实际上,你在这个UI看到的每个按钮都是完全相同的预置:
设计者构建UI模板的速度大大加快。现在,在MRTK中构建UI真的非常有趣。简单的构造块,组合在一起,并形成更复杂的布局。
2. 计量
大规模使用UI的另一个问题是,设计语言/库对度量有非常具体的要求,既有可用性方面的考虑(最小接触目标、可读性等),又有设计方面的要求(填充、边距、角半径)。这是我们在混合现实中的设计偏离了大多数设计师在2D环境中所习惯的典型工作流程的最关键方面之一。过去,我们不仅在绝对坐标中指定了所有内容,没有任何弯曲或对齐参数,而且对所有内容都使用了物理的、真实的单位。所有用户界面均以毫米为单位设计。brand指导原则是以毫米为单位,边距、填充、边沟、间距都是毫米。甚至字体都是以毫米为单位指定。
这存在一定的好处。值得注意的是,我们面对的是真实的物理环境。混合现实中的UI不仅仅是屏幕显示的抽象信息;它本质上是存在于真实的物理世界中的真实物理对象。在开发过程中的某个阶段,它必须具有定义的物理大小和物理单元。我们对全息图的可用性同样有着非常严格的要求。我们的用户研究告诉我们,某些触控目标尺寸(32mm x 32mm,或最小的24mm)可以用于与手指进行三维立体按压交互。
然而,这种对物理单位的依附同样有缺点。首先,对于典型的前端设计师而言,这是一个陌生的工作环境,他们习惯于非物理设计单元,如em、rem、%、vh。传统的2D设计同样有DPI或屏幕密度的概念。但在混合现实中,设计与物理世界之间的关系更为密切。
最直接的缺点是,在这个以绝对物理单位指定所有内容的系统中,根本没有缩放空间。在混合现实中,在特定情况下依然需要放大或缩小整个UI布局或设计。这在为远距离、大型对象重用UI布局时十分常见(。对于笔划、轮廓和角半径等UI元素,我们使用着色器驱动的渲染技术。当仅以绝对物理单位指定时,这种计量值无法与设计的其余部分保持成比例一致。如果将32mm x 32mm按钮放大5倍,则1mm和5mm设计元素仍将保持1mm厚和5mm宽。尽管以绝对单位指定,但它们在比例上并不正确。
这令人十分困惑,但问题的核心是:没有RectTransforms或Canvas,就没有维度。只有尺度。对于笔划或角半径等元素,我们必须“绝对地”指定它们,以便在用于调整其大小和形状的缩放操作中保持一致。但当整个UI布局需要放大或缩小时,绝对测量值将成比例地不正确。
为了尽可能避免混淆,我们看一看可视化示例。首先,我们来看看当我们想“放大”基于非RectTransform的Dialog控件时会发生什么:
你可以看到,所有在物理单位中绝对指定的笔划、角半径等都保持“物理正确”,笔划总是精确到1mm。但随着其余设计的放大和缩小,它们变得不成比例。
你可能会说“只需将所有元素指定为相对于总体设计比例的
相对
…”问题是,如果没有RectTransform/Canvas,就没有任何相关元素。如果一切都只是缩放操作之上的缩放操作,那么就没有办法定义任何真正的相对甲量。每一个相对计量都是相对于它的父对象,它会应用任意数量的破坏性缩放操作。没有设计的“根”,也就没有可用于指定相对测量单位的“DPI”。
你怎么解决这个问题?答案是非物理设计单元,具有一定的“比例因子”。非物理单位和设计比例因子仅适用于Canvas和RectTransform布局,其中Canvas本身充当“设计根”,单个UI元素不缩放,而是调整大小。
UI是在任意的非物理单元中设计。现在我们叫它u吧,因为没有更好的名字。
我们同时定义比例因子或计量。MRTK3的组件库默认使用1mm到1u的比例计量,但微软的其他组件库使用了其他计量,如1mm到3u。在MRTK3中,我们可靠的32mm按钮现在计量为32u x 32u。在默认比例(1mm:1u)下,我们得到了我们的标准,推荐的32mm目标。但最关键的是,我们同时可以随时自由地重新调整计量值,这样我们可以在保持设计完整性的同时放大和缩小整个设计。
这是一个基于RectTransform的Dialog控件。即使我们将其从0.5x缩放到2x,所有的brand和视觉元素依然保持成比例正确。
现在,当设计师在Figma之类的外部工具中构建布局时,他们可以向工程师或技术设计师提供红线批注,这实际上是可以实现的。通过使用设计单元而不是物理单元,再加上强大的实时布局、灵活和对齐系统,我们可以实现更现代、更稳定的设计,无需借助手动布局和计算。
3. 平面世界中的体三维UI
与3D用户界面交互,同时遵循传统的2D界面“隐喻”(如剪切和滚动)十分困难。我们在MRTK3中的UI控件基本上是真实的实体对象,具有深度、体积和厚度。
在UI隐喻中包含这种对象(如“滚动视图”)可能非常棘手;在体三维情景中,“剪裁”看起来像什么?通常,UI具有光线投射/命中目标,这种目标表示为2D矩形,可以重叠和相交,并且可以通过2D剪裁矩形进行剪裁。
对于3D体三维UI,它看起来像什么?Unity UI通常具有基于图像的光线投射命中测试功能,如上所述,这通常不会影响我们的体三维UI,因为我们需要完整的物理化碰撞器来进行3D按压交互和自由形式的3D布局。碰撞器不能像基于图像的光线投射目标那样轻易“剪裁”,对吗?
作为采用现有Unity UI结构的努力,我们开发了一种以组件对组件方式裁剪体三维用户界面及其相应物理碰撞器的系统。碰撞器以深度校正(平面)方式剪裁,允许具有厚度和体积的3D UI精确匹配Unity UI滚动视图/剪裁矩形的边界。
在MRTK的前几次迭代中,当碰撞器离开裁剪区域的足迹时,我们只启用或禁用碰撞器。这导致用户意外按下90%不可见/被剪裁的按钮,而依然可见的按钮没有响应。通过精确地将碰撞器剪切到剪切区域的边界,我们可以在滚动视图的边缘实现毫米级的3D UI交互。更好的是,这一切都基于现有的Unity UI布局组和滚动组件,因此所有的滚动物理保持不变,同时与传统的2D输入兼容,如鼠标滚轮、多点触控触控板和触控屏。
4. 输入
我们的3D体三维UI支持大量输入方法和平台的。在XR中,你有
-
注视+按压交互
-
手部射线,
-
基于手部追踪的按压/戳压
-
注视+语音演讲
-
全局语音
-
运动控制器射线
-
运动控制器点戳
-
注视驻留
-
空间鼠标
当考虑平面屏幕/2D输入时,列表会进一步扩展……
-
触控屏/多点触摸
-
2D鼠标
-
手柄
-
无障碍控制器
-
键盘导航
Unity的UI系统非常适合2D输入。他们提供现成的触控屏、鼠标和手柄输入。他们甚至提供了基本的点击式XR输入。但遗憾的是,当你看到我们尝试用MRTK解决XR输入空间的多样性和丰富性时,基本的Unity UI输入并不足够。
Unity UI输入基本上是二维。最明显的差距是三维立体按压交互;当然,指针事件可以从手指与画布平面的交点进行模拟,但XR输入比这丰富得多。你的手指可以穿过按钮的一半,或者你的注视+按压交互可以夹到一半,或者手部、控制器、注视点、语音的任意组合。当UI是一个具有物理特征、尺寸和体积的真实物理对象时,你需要一套更丰富的交互系统。
谢天谢地,MRTK3利用了Unity提供的优秀XR Interaction Toolkit,这是一个非常灵活的描述3D交互和操作的框架。它功能强大,足以描述我们所有复杂的XR交互,如戳、按、捏和注视。但是,它远没有处理传统输入的设备,如鼠标、触控屏或手柄。当然,我们可以重新实现Unity UI已经提供的手柄或鼠标输入,但这听起来非常费神。如果我们能将XRI的灵活性与Unity UI输入的开箱即用功能结合起来,那又会怎么样呢。
利用我们的组件库,我们在适配器和转换的微妙捣鼓下做到了这一点。每个MRTK3 UI控件都同时是UnityUI Selectable和XRI Interactiable。
我们基于XRI的交互器可以在UI控件执行丰富、详细的3D交互,包括其他不可能的特殊行为,如模拟“选择性”或“按下”。但与此同时,我们可以获得触控屏输入、鼠标输入,甚至是定向手柄导航和输入,而无需自己实现任何输入处理。
我们通过将传入的UnityUI事件(从Selectable)转换为XRI指令来实现这一点。XRI Interactible是我们用户界面中真理的最终来源,开发者需要订阅的唯一“点击”事件是Interactible事件。然而,使用代理交互器,我们将UnityUI事件(如OnPointerDown)转换为代理交互器上的等效操作(如XRI Select或Hover)。这样,任何UnityUI输入都会转换为等效的XRI事件,所有代码路径都会聚合到相同的OnClicked或OnHoverEnter结果。
这对UI意味着,你可以在数量惊人的大量设备和平台使用完全相同的UI预置、完全相同的事件和完全相同的界面布局,同时保留MRTK-UX众所周知的丰富和令人愉快的细节。
5. 总结
这篇文章可以再多写几十页,并介绍所有MRTK3 UX工具和特性。但是,探索它们的最好方法是动手构建。你可以参阅我们的全新系统文档,并学习如何设置自己的MRTK3项目。或者,你以通过这个mrtk3分支克隆这个git存储库,直接查看我们的示例项目。
未来,我将编写更多关于使用新工具构建体三维UI的指南、分解图和教程。我希望你喜欢深入探索我们为MRTK3构建的全新UI系统,我们非常期待你用我们的新工具,并构建出令人称叹的项目。就我个人而言,我喜欢华丽、丰富、富于表现力和令人愉快的用户界面,我非常期待看到社区给我们大家带来的惊喜。