了解如何将空间配件整合到你的 app 中。展示虚拟内容、与 app 进行交互、在空间中进行追踪,并获取有关交互效果的信息,进一步提升 visionos 上的虚拟体验。

视频封面
视频地址

此文章由AI生成,可能存在错误,如有问题,请联系djs66256@163.com

探索 visionOS 上的空间配件输入:打造沉浸式雕刻体验

Apple 在 visionOS 中引入了空间配件支持功能,为开发者提供了全新的交互方式。本文将通过一个空间雕刻应用的开发实例,详细介绍如何利用 PlayStation VR2 Sense 控制器和罗技 Muse 等空间配件,在 visionOS 应用中实现精确的追踪和交互。

空间配件概述

visionOS 原本采用”眼手优先”的输入范式,而新加入的空间配件支持则扩展了这一体验。目前支持两款空间配件:

  • PlayStation VR2 Sense 控制器:具有按钮、摇杆、扳机键和精准空间追踪,非常适合游戏场景
  • 罗技 Muse:配备力传感器和触觉反馈,适用于生产力与创意应用

这些配件可以用于全空间和共享空间应用,通过结合 Vision Pro 的摄像头和配件自身的传感器实现位置与旋转追踪。

应用开发基础

项目设置

首先需要在 Xcode 项目中进行配置:

  1. 在 plist 中添加”Spatial Gamepad”支持
  2. 在”Accessory Tracking Usage”字段描述配件用途(如”追踪配件移动来雕刻虚拟粘土”)

配件连接管理

使用 Game Controller 框架管理配件连接:

NotificationCenter.default.addObserver(forName: NSNotification.Name.GCControllerDidConnect, object: nil, queue: nil) {
  notification in
    if let controller = notification.object as? GCController,
       controller.productCategory == GCProductCategorySpatialController {
             
    }
}

需要监听 GCControllerDidConnect 和 GCStylusDidConnect 通知来处理配件的连接和断开事件。

实现配件追踪与交互

锚定虚拟内容

在配件末端显示虚拟笔尖需要使用锚定技术。创建 AccessoryAnchoringSource 并锚定到配件的”aim”位置:

func setupSpatialAccessory(device: GCDevice) async throws {
    let source = try await AnchoringComponent.AccessoryAnchoringSource(device: device)
    guard let location = source.locationName(named: "aim") else {
        return
    }
    let sculptingEntity = AnchorEntity(.accessory(from: source, location: location),
                                     trackingMode: .predicted)
}

追踪模式可选择:

  • predicted(预测):响应速度快,适合渲染和低延迟交互
  • continuous(连续):精度高但延迟较高

获取变换矩阵

使用 SpatialTrackingSession 获取配件 AnchorEntity 的变换:

let session = SpatialTrackingSession()
let configuration = SpatialTrackingSession.Configuration(tracking: [.accessory])
await session.run(configuration)

添加触觉反馈

为增强沉浸感,可以为配件添加触觉反馈:

let stylus: GCStylus = ...
guard let haptics = stylus.haptics else {
    return
}
guard let hapticsEngine: CHHapticEngine = haptics.createEngine(withLocality: .default) else {
    return
}
try? hapticsEngine.start()

高级功能实现

响应式工具栏

从 AnchorEntity 获取 ARKit 的 AccessoryAnchor 可实现响应式工具栏:

func getAccessoryAnchor(entity: AnchorEntity) -> AccessoryAnchor? {
    if let component = entity.components[ARKitAnchorComponent.self],
        return accessoryAnchor
    }
    return nil
}

利用 handedness 属性决定工具栏显示位置:

  • 左手握持时显示在正X轴方向
  • 右手握持时显示在负X轴方向

纯 ARKit 实现

对于自定义渲染的应用,可直接使用 ARKit API 追踪配件:

  1. 创建 Accessory 对象
  2. 使用 Accessory 追踪提供者
  3. 处理配件连接/断开事件

设计考量

开发空间配件应用时需注意:

  1. 视图应同时接收手势和游戏控制器输入
  2. 全空间应用可使用 .persistentSystemOverlays 和 .upperLimbVisibility 增强沉浸感
  3. 应同时支持配件和手部输入
  4. 应用商店可展示”支持空间游戏控制器”或”需要空间游戏控制器”徽章

总结

空间配件为 visionOS 应用带来了精细输入控制和触觉反馈的新维度。通过 GameController、RealityKit 和 ARKit 的组合,开发者可以创造高度沉浸的交互体验。从游戏到创意工具,空间配件的应用潜力才刚刚开始显现。

相关视频

RealityKit 的新功能
使用 ARKit 打造更出色的空间计算体验
使用 RealityKit 构建空间绘画 App
利用虚拟和物理游戏控制器
游戏控制器的进展