可交互对象 - MRTK3

MRTK 建立在 Unity 的 XR 交互工具包提供的 XRBaseInteractable 之上。 MRTK 完全支持现有的可交互行为和 API,且所有自定义交互对象都遵循现有的 XRI 可交互 API。

对于不熟悉 XRI 的开发人员而言,强烈建议先查看 Unity 的 XRI 体系结构文档

为了扩展 XRI 中包含的可交互机制,MRTK 提供了两个基类,可用于构建高级交互,它们之间存在扩展关系。

Interactables inheritance diagram

  • MRTKBaseInteractable : XRBaseInteractable
    • 此类为不同类型的交互器提供筛选和标记。 虽然基本 XRI XRBaseInteractable 不区分交互器类型,但 MRTKBaseInteractable 提供了便于使用的函数,可用于检查是否存在常见类型的交互。 便于使用的属性(例如 IsGazeHoveredIsGrabSelected)是查询参与的交互器是否实现给定接口的快捷方式(相应地是 IGazeInteractorIGrabInteractor)。 与遍历 interactorsHoveringinteractorsSelecting 的列表相比,使用这些标志可以实现更好的性能。 此外 MRTKBaseInteractable 还可以筛选/拒绝某些类型的交互器,以防开发人员希望排除特定的输入形式。
  • StatefulInteractable : MRTKBaseInteractable
    • 虽然 MRTKBaseInteractable 添加标志和筛选器,并避免将任何其他状态添加到可交互对象,但 StatefulInteractable 引入了涉及状态的有用功能,例如切换和变量选择。

严格分离状态和视觉对象

在 MRTK 2.x 中,可交互对象通常负责驱动自己的视觉效果,包括按压 3D 按钮、悬停效果,甚至只是在单击时更改颜色。 这种方法的局限性在于交互逻辑与视觉对象紧密相关。 如果要重新设计视觉对象或使用不同尺寸/形状/位移/等的按钮,交互脚本本身需要改变。

在 MRTK3 中,可交互对象是纯状态和交互。可交互对象不会根据其内部状态呈现任何视觉变化或效果。 它仅是状态和交互逻辑的集合,在视觉呈现设置之间具有高度可移植性。

Strict isolation of state and visuals

同样的 PressableButton 脚本可以用来创建一个软球、一个类似于“触控板”的可按压平面,或者一个在按下时发布网络事件的抽象可按压按钮。 该 PressableButton 脚本甚至不受位置影响,它可以位于画布内,或位于刚体上。

为驱动视觉对象,系统使用单独的“视觉驱动程序”从可交互对象轮询状态并呈现相应的反馈。 StateVisualizer 是推荐的低代码方法,用于根据可交互状态驱动常见的视觉反馈效果,但是开发人员可以自由地编写自己的自定义视觉驱动程序。 例如,我们的按钮组件通常使用 StateVisualizer 来实现高级的基于 3D 和着色器的反馈效果,但我们也提供了一个示例 BasicPressableButtonVisuals 来展示如何在代码中创作出简单的视觉驱动程序。

变量选择

与基本 XRI 功能相比,StatefulInteractable 最有用的 附加功能是对变量 Selectedness 的支持。 选中或未选中基本 XRI 可交互对象时,MRTK 的 StatefulInteractable 可以是选中的任何浮点分数。

此概念在 XR 中很有帮助,因为几乎所有形式的输入都不再是二进制状态。 运动控制器通常具有模拟扳机(或模拟手柄),手部交互可提供可变的握力,体积按压交互可以按下按钮或不同面积的可按压表面。 在 XR 中随处可见这些可变的模拟交互,而 MRTK 的功能则可以帮助开发人员在这些模拟输入的基础上构建令人愉快的交互体验。

各种不同的交互器和交互类型都可以共同为可交互对象提供选择。 值得注意的是,实现 IVariableSelectInteractor 的所有交互器都对模拟选择量有共享,这通常是通过所有参与的交互器的 max() 实现的。 此变量量与 Vanilla 式交互器中的二进制非变量选择相结合。

对于像 PressableButton 这样的派生类,将重写 Selectedness() 函数以向选择计算添加额外的“成分”。 实现 IPokeInteractor 的交互器可以基于其物理位置以及它们在物理上的按压方式来增加选择。 其他派生类可以引入其他任意选择形式。

Variable selectedness

对于 MRTK 提供的互操作对象,Selectedness()isSelected 将始终“一致”,也就是说,如果没有相应的 XRI isSelectedinteractorsSelecting 中随附的交互器,则绝不会出现 Selectedness() 大于 SelectThreshold 的情况。

重要

诚然,自定义可交互子类可以将 Selectedness 重写为与 XRI isSelected 完全断开连接的一些其他值;但我们的可交互对象不会执行此操作,也强烈建议不要这样做。 除非存在特殊情况,否则请勿编写没有相应交互器的交互 XRI 选择能满足绝大多数的情况,且生成的任何自定义交互都应编写为交互器。

在创建支持确定 Selectedness() 的新方法的自定义可交互对象时,只需重写该方法并将新选择与现有选择结合起来。 如果使用 StateVisualizer 或任何其他侦听变量选择的视觉层,它将相应地响应新选择类型。

将 UGUI 事件映射到 XRI

在某些情况下,需要让可交互对象响应 UGUI 事件,例如鼠标、手柄或触摸屏输入。 UGUIInputAdapter 是 UGUI Selectable,它接收 UGUI 事件并将它们转发给 CanvasProxyInteractor(如果有)。

UGUI adapter flow

UGUIInputAdapter 通知 CanvasProxyInteractor UGUI 事件时,它在相关的可交互对象上发出等效的 XRI 操作。 UGUI 输入和 XRI 操作之间的映射存在某种程度的丢失,是活动开发领域。

有了这个系统,为沉浸式平台、手势、运动控制器和 3D 输入而设计的现有 XRI 交互系统可以同样有效地响应鼠标和手柄等辅助性 2D 控制手段。