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 提供了完整的构建支持:
- 选择 visionOS build target
- 启用 XR Plug-in
- 原生插件需要重新编译(.mm 源码文件无需修改)
- 从 Unity 生成 Xcode 项目
- 在 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.Wrist、IndexTip、IndexIntermediate获取三个关键关节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
- Create immersive Unity apps — Unity 在 visionOS Shared Space 中的沉浸式应用开发
- Build great games for spatial computing — 空间计算游戏开发技术概览
- Discover Metal for immersive apps — 用 Metal 直接渲染 visionOS 完全沉浸式体验
评论
GitHub Issues · utterances