Snapdragon Spaces 开发指南(8)
5.4.3 XR 交互工具包示例
此示例演示了基于操作的输入系统和 XR 交互工具包组件的用法。有关新输入系统和 XR Interaction Toolkit 包的基本信息,请参阅Unity 文档 。
示例如何工作
该示例演示了如何与场景中的 UI 和其他游戏对象进行交互。
浮动 UI 面板提供了可交互的常用 UI 元素,例如按钮和滚动条。虽然按钮可与凝视指针和设备指针一起使用,但示例中的滚动条仅可与设备指针一起使用。此外,场景中的另一个 UI 元素展示了来自主机控制器触摸板的输入。
最后,可以使用设备指针抓取交互式立方体对象,以演示 3D 对象交互。为了使其成为一个交互式对象,它需要具有以下组件:
- 对撞机
- 刚体
- XR Grab Interactable(参考XR 交互管理器)
![](https://i-blog.csdnimg.cn/blog_migrate/20a5fb85f090e113740ed659a7f23706.png)
设备指针控制器
示例中包含的设备指针预制件由三个主要组件组成:
- XR控制器(基于操作)组件负责接收来自 XR 输入设备的输入。在示例中,操作映射中的输入操作引用被分配给Position、Rotation、Select、Activate和UI Press ,如下图所示。
- XR 射线交互器是多种类型的交互器之一。它可以通过使用光线投射与场景中的 Unity UI 元素以及有效的交互对象进行交互。XR 射线交互器应引用场景中当前的XR 交互管理器。
- XR Interactor Line Visual和相应的Line Renderer组件用于从控制器的原点沿着控制器的前进方向渲染一条线。默认情况下,它的颜色为红色,但是一旦它击中有效的交互式对象,它就会将颜色更改为绿色。
![](https://i-blog.csdnimg.cn/blog_migrate/5179c395b2c13ab8d84c24038cde4b78.png)
5.5 合成层组件
交互预制件包含一个凝视指针预制件,它利用合成层来渲染内容。
凝视指针
凝视指针由以下游戏对象组成:
XR Gaze Interactor游戏对象有一个Spaces Composition Layer组件。这将创建一个显示视图锁定内容的四层。与UI Overlay Camera GameObject 相结合,这会以提高指针稳定性和清晰度的方式呈现注视指针 UI 元素,但会牺牲一些性能。
支持的渲染器
仅当使用OpenGLES3作为图形 API时才支持Spaces Composition Layer组件,而不是Vulkan。当前选择的图形 API 可以在项目设置 > 播放器 > 其他设置 > 渲染 > 图形 API 中查看。
- 图层纹理:将渲染到视图锁定四层的纹理。
- 范围:要渲染的四层的大小(以米为单位)。
- Orientation:四层的方向,相对于主相机的视图。四层只有正面,如果背对主摄像头则不可见。
- Position:四层的位置,相对于主相机的视图。
- 排序顺序:四元图层的渲染顺序。较低的数字代表较低的层。请参阅排序顺序。
配置示例
在 Snapdragon Spaces SDK 示例中,视图锁定凝视指针配置如下:
- 空间合成层由 10cm x 10cm 四层组成,合成到主相机前面 2m 的位置。
- 它将UI 叠加渲染纹理的内容绘制到此四边形中。
- 该图像的内容由UI Overlay Camera在其目标纹理字段中捕获。
- 相机使用Culling Mask仅捕获UI Overlay层中的内容。
- UI Overlay层上的唯一元素是Reticle Canvas GameObject 及其子元素。
- Reticle Canvas的Render Camera属性设置为UI Overlay Camera。
空间合成层组件可以根据需要配置静态或动态纹理。启用或禁用组件将隐藏/显示它们呈现的内容。
5.6 感知样本
5.6.1 锚
此示例演示了如何创建和销毁本地锚点以准确跟踪现实世界中的点。有关锚点的基本信息以及 AR FoundationAR Anchor Manager组件的作用,请参阅Unity 文档 。为了使用此功能,必须在位于 下的 OpenXR 插件设置中启用它Project Settings > XR Plug-in Management > OpenXR (> Android Tab)。
示例如何工作
首先,确保Spatial Anchors在 OpenXR 项目设置中启用该功能。
出于放置目的,透明的放置小控件视觉对象漂浮在相机中心 1 米距离处。每帧都会从头部中心向前投射一条光线,以便定位放置小控件相对于现实世界平面的位置。如果检测到命中,放置小控件也会变成黄色。在点击主机控制器上的触摸板或与 UI 面板上的凝视交互后(如果选择凝视交互器则可见),将实例化一个空游戏对象和一个ARAnchor游戏对象。空的 GameObject 有一个透明的 Gizmo 网格,AR 会话将跟踪它。AR 锚点小玩意将通过 的ARAnchorManager事件进行更新anchorsChanged,以表示其跟踪状态。
public GameObject GizmoTrackedAnchor;
public GameObject GizmoUntrackedAnchor;
private override void Start() {
FindObjectOfType<ARAnchorManager>().anchorsChanged += OnAnchorsChanged;
}
private void OnAnchorsChanged(ARAnchorsChangedEventArgs args) {
foreach (var anchor in args.added) {
...
}
foreach (var anchor in args.updated) {
Destroy(anchor.transform.GetChild(0).gameObject);
var newGizmo = Instantiate(anchor.trackingState == TrackingState.None ? GizmoUntrackedAnchor : GizmoTrackedAnchor);
newGizmo.transform.SetParent(anchor.transform, false);
}
foreach (var anchor in args.removed) {
...
}
}
摧毁所有锚点
![](https://i-blog.csdnimg.cn/blog_migrate/0e7b6ea8a7dcda6b54effa789f14c5bd.png)
Destroy All Anchors所有锚点和小玩意都可以通过单击用户界面来销毁。删除命令会延迟发出,以防止在应删除所有内容后使用“选择”按钮创建锚点。
空间锚点
警告
确保环顾您的环境,以便生成更好的跟踪地图并减少保存和加载时间。一次保存多个锚点会阻塞主线程,因此应该使用回调来保存任何后续锚点。
通过Spaces Anchor Store在 旁边添加一个组件AR Anchor Manager,可以将锚点保存在本地,以便在以后的会话中进行识别和跟踪。该组件提供以下 API 用于加载和保存锚点、删除已保存的锚点以及清除锚点的本地存储。
namespace Qualcomm.Snapdragon.Spaces
{
public class SpacesAnchorStore
{
public void ClearStore();
public void SaveAnchor(ARAnchor anchor, string anchorName, Action<bool> onSavedCallback = null);
public void SaveAnchor(ARAnchor anchor, Action<bool> onSavedCallback = null);
public void DeleteSavedAnchor(string anchorName);
public void LoadSavedAnchor(string anchorName, Action<bool> onLoadedCallback = null);
public void LoadAllSavedAnchors(Action<bool> onLoadedCallback = null);
public string[] GetSavedAnchorNames();
public string GetSavedAnchorNameFromARAnchor(ARAnchor anchor);
}
}
在这些信息转移到脚本 API 之前,以下是这些方法的简短描述:
- ClearStore
- 清除锚点的本地存储。
- SaveAnchor
- AR Anchor通过给定名称或生成的哈希来保存对象。可以在完成时调用回调。
- DeleteSavedAnchor
- 从本地存储中按名称删除已保存的锚点。
- LoadSavedAnchor
- 从本地存储加载锚点并尝试在场景中定位锚点。如果找到锚点,AR Anchor则会实例化一个对象。added加载的锚点将在 ARAnchorManager 的事件中列出anchorsChanged。可以使用 检索已保存锚点的名称GetSavedAnchorNames。可以在完成时调用回调。
- LoadAllSavedAnchors
- 从存储中加载所有锚点并尝试在场景中找到它们。与 类似LoadSavedAnchor,AR Anchor对象将在识别后被实例化。
- GetSavedAnchorNames
- 按名称返回所有已保存的锚点。
- GetSavedAnchorNameFromARAnchor
- 如果跟踪的AR Anchor对象是以前保存的对象,则此方法将返回其名称,否则返回空字符串。此方法可用于检查锚点是否已保存。
保存、删除和加载示例中的锚点
通过启用Save new anchors to local store切换,每当创建新锚点时,它将被保存到本地应用程序商店。这意味着只要AR Anchor Manager场景中存在此保存的锚点,就可以像任何其他常规锚点一样重新创建和跟踪。为了区分常规锚点和保存的锚点,将在所述锚点的中心生成额外的立方体网格。如果立方体是红色的,则意味着保存的锚点没有被跟踪,如果它是白色的,则表示正在被跟踪。通过单击Load All Saved Anchors本地存储中的所有锚点将被加载,并且底层功能将尝试找到它们。另一方面,单击Clear Store将删除本地存储中保存的所有锚点。此操作不会破坏从商店加载的任何现有锚点。
5.6.2 手部追踪
警告
Spaces Hand 组件已被弃用,取而代之的是QCHT 包中的组件,并将在未来版本中删除。示例应用程序中当前的手部跟踪场景包含在QCHT 包中,必须导入该场景才能使示例正常工作。
空间手部经理
警告
Spaces Hand Manager 组件已被弃用,取而代之的是QCHT 包中的组件,并将在未来版本中删除。
该Spaces Hand Manager组件的类型ARTrackableManager和编程方式与 AR Foundation 的所有其他管理器类似 - 通过提供回调函数来检索添加、更新和删除项目形式的更改
public void Start() {
spacesHandManager.handsChanged += OnHandsChanged;
}
...
private void OnHandsChanged(SpacesHandsChangedEventArgs args) {
foreach (var hand in args.added) {
...
}
foreach (var hand in args.updated) {
...
}
foreach (var hand in args.removed) {
...
}
}
它还提供了一个检查器字段来定义在检测手时应生成的默认预制件。示例中的预制件Default Spaces Hand由两个附加组件组成,如下图所示。以下各节将详细介绍它们。
![](https://i-blog.csdnimg.cn/blog_migrate/351e3d60f1d7ca8ff6d814ff9bd9f867.png)
空间 手部组件
警告
Spaces Hand 组件已被弃用,取而代之的是QCHT 包中的组件,并将在未来版本中删除。
该组件是获取所有手部相关数据的通用接口。它是类型ARTrackable,因此具有常见属性,如TrackableID、TrackingState和将由被跟踪手的腕关节定义的Pose 。
它还提供了另外三个属性:
- IsLeft是一个布尔值,如果跟踪的手是左手,则返回 true。否则,返回值为 false。
- 关节是一系列Qualcomm.Snapdragon.Spaces.SpacesHand.Joint类型。该类型具有以下属性:
- Pose是一个 Unity 姿势类型,返回手关节的姿势。
- Type是类型Qualcomm.Snapdragon.Spaces.SpacesHand.JointType并返回一个枚举值,该值是针对哪个手关节。
- 手势是类型Qualcomm.Snapdragon.Spaces.SpacesHand.Gesture,具有以下属性:
- Type是类型Qualcomm.Snapdragon.Spaces.SpacesHand.GestureType并返回一个枚举值,该值表示检测到手部的手势。
- GestureRatio是一个介于 0 和 1 之间的浮点值,指示应用手势的程度。
- FlipRatio是 -1 到 1 之间的浮点值,指示是从后面 (-1)、从前面 (1) 还是在中间检测到手势。
有关手势的更多信息,请参阅交互手势文档。
namespace Qualcomm.Snapdragon.Spaces.SpacesHand
{
public enum JointType
{
PALM = 0,
WRIST = 1,
THUMB_METACARPAL = 2,
THUMB_PROXIMAL = 3,
THUMB_DISTAL = 4,
THUMB_TIP = 5,
INDEX_METACARPAL = 6,
INDEX_PROXIMAL = 7,
INDEX_INTERMEDIATE = 8,
INDEX_DISTAL = 9,
INDEX_TIP = 10,
MIDDLE_METACARPAL = 11,
MIDDLE_PROXIMAL = 12,
MIDDLE_INTERMEDIATE = 13,
MIDDLE_DISTAL = 14,
MIDDLE_TIP = 15,
RING_METACARPAL = 16,
RING_PROXIMAL = 17,
RING_INTERMEDIATE = 18,
RING_DISTAL = 19,
RING_TIP = 20,
LITTLE_METACARPAL = 21,
LITTLE_PROXIMAL = 22,
LITTLE_INTERMEDIATE = 23,
LITTLE_DISTAL = 24,
LITTLE_TIP = 25
}
}
namespace Qualcomm.Snapdragon.Spaces.SpacesHand
{
public enum GestureType
{
UNKNOWN = -1,
OPEN_HAND = 0,
//FLIP = 1,
GRAB = 2,
//UP = 3,
//DOWN = 4,
//SWIPE = 5,
//SWIPE_OUT = 6,
PINCH = 7,
POINT = 8,
VICTORY = 9,
//CALL = 10,
METAL = 11
}
}
Spaces 手关节可视化器组件
警告
Spaces Hand Joint Visualizer 组件已被弃用,取而代之的是QCHT 包中的组件,并将在未来版本中删除。
该组件提供了一些属性来更改联合可视化的外观,例如:
- JointMesh是应该为每个关节实例化的网格。
- JointMaterial是应该应用于网格上的材质。
- JointMeshScale是 0.005 到 0.05 之间的浮点值,定义应应用于网格的缩放。
- UseNormalizedColors是一个布尔值。如果设置为 true,所应用材质着色器的_Color属性将由组件着色。
在示例中,UnityEngine 中包含的简单球体网格被设置为 JointMesh ,默认材质被设置为JointMaterial。