Design for spatial interaction
Augmented Reality 进阶 20m

为空间交互而设计

Design for spatial interaction

2021年6月10日

在 Apple 官方观看视频

一句话判断

ARKit 中的空间交互设计不是”在 3D 空间里放个 UI”那么简单——手部追踪(Hand Tracking)和人脸追踪的融合让 AR 体验从”看”变成了”触摸”。

这场 Session 讲了什么

Session 从设计角度讲解了 ARKit 中空间交互的原则和最佳实践。iOS 15 的 ARKit 增强了对 LiDAR 场景理解的能力,同时改进了手部追踪和人脸追踪的精度。

空间交互的核心挑战是:用户在 AR 场景中没有物理反馈。点击屏幕上的按钮你能感觉到震动,但在 AR 空间中”抓住”一个虚拟物体,你的手什么也感觉不到。Session 讨论了如何通过视觉反馈(高亮、阴影变化)和音频反馈来弥补触觉的缺失。

还介绍了不同交互模式的适用场景:直接交互(用手指触碰 AR 物体)适合近距离操作,间接交互(通过屏幕射线选择)适合远距离操作,面部朝向交互(转头选择)适合 hands-free 场景。

值得深挖的点

无触觉反馈的替代方案

在真实世界中,你拿起杯子时手指感受到压力和温度。在 AR 中”拿起”一个虚拟杯子,什么感觉都没有。Session 给出的方案是多层反馈叠加:视觉上物体在手靠近时轻微放大(暗示被”选中”)、改变颜色或添加光晕;音频上播放一个简短的”拾取”音效;如果设备支持,触发触觉反馈。这种多感官反馈的设计比纯视觉反馈让用户更有操作确认感。

LiDAR 场景理解的深度利用

有 LiDAR 的设备(iPad Pro、iPhone Pro)能实时构建周围环境的 mesh。这意味着虚拟物体可以”放在”真实的桌子上、被真实的墙壁遮挡。Session 建议利用场景理解做物理正确的交互——虚拟球在真实地板上弹跳,虚拟角色绕过真实的椅子行走。这种环境感知是”看起来对”和”感觉对”的区别。

代码片段

配置 ARSession 支持手部追踪

import ARKit

let configuration = ARWorldTrackingConfiguration()

// 启用场景几何(需要 LiDAR)
configuration.sceneReconstruction = .mesh

// 启用手部追踪
if ARBodyTrackingConfiguration.isSupported {
    // 手部追踪在 iPadOS 上可用
    let handConfig = ARBodyTrackingConfiguration()
    handConfig.sceneReconstruction = .mesh
    session.run(handConfig)
} else {
    // 降级:使用屏幕射线交互
    session.run(configuration)
}

实现虚拟物体的射线选择

// 从屏幕中心发射射线选择 AR 物体
func selectObject(at point: CGPoint, in sceneView: ARSCNView) -> SCNNode? {
    let hitResults = sceneView.hitTest(point, options: [
        .boundingBoxOnly: true,
        .searchMode: SCNHitTestSearchMode.closest.rawValue
    ])
    
    // 找到第一个可选中的虚拟物体
    if let hit = hitResults.first, hit.node.name == "selectable" {
        // 视觉反馈:高亮选中的物体
        highlightNode(hit.node)
        // 音频反馈
        playSelectionSound()
        // 触觉反馈
        UIImpactFeedbackGenerator(style: .light).impactOccurred()
        return hit.node
    }
    return nil
}

处理手部手势交互

// 检测捏合手势(拇指和食指靠近)来"抓住"虚拟物体
func processHandAnchor(_ anchor: ARAnchor) {
    guard let handAnchor = anchor as? ARHandAnchor else { return }
    
    // 获取拇指尖和食指尖的位置
    let thumbTip = handAnchor.handSkeleton?.joint(.thumbTip)
    let indexTip = handAnchor.handSkeleton?.joint(.indexFingerTip)
    
    guard let thumb = thumbTip, let index = indexTip else { return }
    
    // 计算两指距离
    let distance = distance(thumb.position, index.position)
    
    if distance < 0.03 {  // 3cm 以内判定为捏合
        isPinching = true
        // 触发抓取动作
        grabNearestObject()
    } else {
        isPinching = false
    }
}

最佳实践

设计原则: 优先使用直接交互(手指触碰)而非间接交互(屏幕射线)。直接交互更直观,学习成本更低。但对于远距离物体,提供射线交互作为备选。所有交互都要有视觉+音频+触觉的组合反馈。

性能考量: 手部追踪和场景 mesh 重建都是计算密集型任务。在 A12Z/M1 的 iPad Pro 上可以同时运行,但在旧设备上可能需要降低 mesh 的精度或频率。用 frame.estimatedDepthData 的分辨率来评估设备能力。

还有什么值得关注

  • ARKit 5 支持在 App Clip 中使用基础 AR 功能。
  • People Occlusion 在 iOS 15 中改进了边缘质量,虚拟物体被真人遮挡时更自然。
  • 新的 Location Anchor 可以在特定 GPS 坐标放置持久化的 AR 内容。
WWDC 2021