WWDC Quick Look 💓 By SwiftGGTeam
Bring your Unity VR app to a fully immersive space

Bring your Unity VR app to a fully immersive space

观看原视频

Highlight

Unity 将完整 XR 生态系统带到 visionOS,开发者可用熟悉的工作流将 VR 项目移植过来。核心路径是:选择 visionOS build target、启用 XR Plug-in、使用 URP 获得注视点渲染和单通道实例化渲染、用 XR Interaction Toolkit 或 Unity Hands Package 将控制器输入适配为手势输入。

核心内容

完全沉浸式体验的两种路径

00:33)Unity 在 visionOS 上支持两种沉浸式体验:

  • 完全沉浸式:替换用户的周围环境,传送到另一个世界。使用 Compositor Services 和 Metal 渲染能力
  • 混合沉浸式:将内容与现实世界的穿透(passthrough)混合。在 Shared Space 中与其他应用共存

本 session 聚焦完全沉浸式路径。另一种路径可参考 “Create immersive Unity apps”。

构建与运行工作流

02:25)Unity 为 visionOS 提供了完整的构建支持:

  1. 选择 visionOS build target
  2. 启用 XR Plug-in
  3. 原生插件需要重新编译(.mm 源码文件无需修改)
  4. 从 Unity 生成 Xcode 项目
  5. 在 Xcode 中构建运行到设备或模拟器

这个流程与 iOS、Mac、Apple TV 目标一致,开发者已经熟悉。

图形管线关键配置

Universal Render Pipeline(URP)

03:29)URP 是推荐选择,因为它支持 visionOS 独有的注视点渲染(Foveated Rendering)。

注视点渲染在镜头中心区域集中更多像素密度,外周区域减少细节。人眼对中心区域更敏感,这个技术在不增加渲染负担的前提下提升视觉质量。

使用 URP 时,静态注视点渲染在整个管线中自动应用,与后处理、相机堆叠、HDR 等功能兼容。自定义渲染通道可以使用 Unity 2022 的新 API 来利用这项技术。

Single-Pass Instanced Rendering

04:40)单通道实例化渲染现在支持 Metal API,默认启用。引擎只为双眼提交一次 draw call,减少剔除、阴影等部分的渲染管线开销,降低立体渲染的 CPU 负担。

如果应用已在其他 VR 平台上正确使用单通道实例化渲染,shader 宏会确保它在 visionOS 上也能工作。

深度缓冲区

05:14)系统合成器使用深度缓冲区进行重投影。每个像素都必须正确写入深度值,缺失深度信息的区域会显示错误颜色。

天空盒通常距离用户无限远,使用 reverse Z 写入深度 0,这需要修改才能在设备上正确显示。Unity 已修复所有内置 shader 的深度写入,但自定义效果(如自定义天空盒、水面效果、透明效果)需要确保每个像素都有深度值。

交互系统:从控制器到手势

visionOS 的交互依赖手和眼。Unity 提供了三层工具来适配:

XR Interaction Toolkit(XRI)

06:09)XRI 是高级交互系统,抽象输入类型,让交互代码跨平台工作。支持 3D 和 UI 对象,响应悬停、抓取、选择等常见交互。

核心组件:

  • Interactable:场景中可接收输入的对象。三种内置类型:Simple(接收交互事件)、Grab(被选中后跟随交互器)、Teleport(定义传送区域/点)
  • Interactor:选择与 Interactable 交互的方式。Direct Interactor(触碰选择)、Ray Interactor(远距离射线选择,支持曲线/直线)、Socket Interactor(定义可接受对象的区域)、Poke Interactor(方向过滤的戳触交互)、Gaze Interactor(凝视交互,自动增大碰撞体)
  • Interaction Manager:协调 Interactor 和 Interactable 之间的交互状态
  • XR Controller:将输入动作传递给 Interactor

Unity Input System

11:35)直接使用系统手势输入。pinch 手势以值形式传递,包含位置和旋转。凝视方向与 pinch 手势在同一帧中传递。

Unity Hands Package

12:12)提供低级别手关节数据,支持跨平台一致访问。可以用来检测手势(如竖起大拇指、伸出食指)或驱动自定义手部网格。

详细内容

检测食指是否伸直

12:46

static bool IsIndexExtended(XRHand hand)
{
    if (!(hand.GetJoint(XRHandJointID.Wrist).TryGetPose(out var wristPose) &&
          hand.GetJoint(XRHandJointID.IndexTip).TryGetPose(out var tipPose) &&
          hand.GetJoint(XRHandJointID.IndexIntermediate).TryGetPose(out var intermediatePose)))
    {
        return false;
    }

    var wristToTip = tipPose.position - wristPose.position;
    var wristToIntermediate = intermediatePose.position - wristPose.position;
    return wristToTip.sqrMagnitude > wristToIntermediate.sqrMagnitude;
}

关键点:

  • XRHandJointID.WristIndexTipIndexIntermediate 获取三个关键关节
  • TryGetPose 获取关节姿态,返回 false 表示关节数据无效
  • 计算手腕到指尖和手腕到中间关节的向量
  • 比较平方距离:如果指尖距离大于中间关节距离,说明食指伸直
  • 可以扩展这个逻辑到其他手指,实现基本手势检测
  • OnHandUpdate 事件中调用,传入左手或右手

XRI 交互管理器配置

Interaction Manager 是 Interactor 和 Interactable 之间的中间人:

// 通常一个 Interaction Manager 管理所有交互
// 也可以为不同场景/菜单配置多个 Manager

// 示例:为游戏场景和菜单分别配置
public InteractionManager gameplayManager;
public InteractionManager menuManager;

void EnterGameplay() {
    gameplayManager.enabled = true;
    menuManager.enabled = false;
}

void EnterMenu() {
    gameplayManager.enabled = false;
    menuManager.enabled = true;
}

关键点:

  • 单个 Interaction Manager 通常足够
  • 多个互补的 Manager 可以激活/禁用特定交互集
  • 例如:游戏场景和菜单使用不同的 Interactable 集合

自定义手部网格

RecRoom 使用原始手关节数据驱动风格化的手部模型:

// 获取所有关节位置
foreach (XRHandJointID jointID in Enum.GetValues(typeof(XRHandJointID)))
{
    if (hand.GetJoint(jointID).TryGetPose(out var pose))
    {
        // 将关节位置映射到自定义骨骼
        customHandMesh.SetJointPosition(jointID, pose.position);
        customHandMesh.SetJointRotation(jointID, pose.rotation);
    }
}

关键点:

  • Unity Hands Package 提供跨平台一致的关节数据
  • 可以驱动任何自定义手部模型
  • 让手部视觉风格与游戏整体风格统一
  • 也可以显示其他玩家的手部模型增强沉浸感

深度缓冲区检查清单

效果类型深度写入要求注意事项
不透明物体必须写入Unity 内置 shader 已修复
天空盒需要修改无限远物体,reverse Z 写 0
透明/水面确保有值自定义效果需检查
粒子系统检查设置部分粒子可能跳过深度写入
后处理不影响在深度测试之后

核心启发

1. 将现有 Unity VR 游戏移植到 visionOS

  • 做什么:把 SteamVR 或 Oculus 上的 Unity 游戏带到 visionOS
  • 为什么值得做:工作流几乎不变:选 target、启用 XR Plug-in、生成 Xcode 项目。URP 自动获得注视点渲染,单通道实例化渲染降低 CPU 开销
  • 怎么开始:升级到 Unity 2022,切换到 URP,检查自定义 shader 的深度写入,用 XRI 替代控制器特定代码,在模拟器上迭代测试

2. 为手势交互设计新的游戏机制

  • 做什么:设计一款原生支持手势的 VR 解谜或动作游戏
  • 为什么值得做:visionOS 的手部追踪精度高、延迟低。XRI 的 Poke Interactor 和 Grab Interactor 让自然手势直接成为游戏输入。无需控制器意味着更低的入门门槛
  • 怎么开始:用 XRI 的 Grab Interactor 实现物体抓取,用 Poke Interactor 实现按钮按压,用 Unity Hands Package 检测特定手势触发特殊能力

3. 构建沉浸式虚拟培训模拟器

  • 做什么:开发医疗、工业或安全培训的 VR 模拟应用
  • 为什么值得做:完全沉浸式空间让用户专注于训练内容。手部追踪让操作虚拟工具的体验接近真实。注视点渲染确保关键细节清晰可见
  • 怎么开始:创建 Immersive Space 并设置为 Full Immersive 风格,用 XRI 的 Socket Interactor 实现工具归位,用 Ray Interactor 实现远距离选择

4. 创建社交 VR 空间

  • 做什么:构建一个多人虚拟聚会或协作空间
  • 为什么值得做:RecRoom 已经证明了这条路可行。Unity 的网络功能可以复用,XRI 的交互系统抽象了输入类型,让跨平台玩家可以一起交互
  • 怎么开始:复用现有的 Unity 多人网络代码,用自定义手部网格展示玩家手部,用 Gaze Interactor 让凝视选择更容易命中

关联 Session

评论

GitHub Issues · utterances