Break into the RealityKit debugger
Spatial Computing 进阶 20m

深入 RealityKit 调试器

Break into the RealityKit debugger

2024年6月10日

在 Apple 官方观看视频

一句话判断

Xcode 今年新增了 RealityKit Debugger——一个类似 View Debugger 的 3D 场景检查器,能让你看到 Entity Hierarchy、每个 Entity 的 Transform 和 Component 属性、还有 3D 视口里直接选中元素检查,从此 debug “为什么我的 3D 内容显示不正常”不再是猜谜游戏。

这场 Session 讲了什么

这场 Session 由 Jeremiah 主讲,以一个”把植物园 App 改造成机器人夜店”的实际项目为线索,演示了 RealityKit Debugger 的完整工作流。

RealityKit Debugger 的使用方式跟 View Debugger 一样:点击 Xcode 底部调试区的”Capture Entity Hierarchy”按钮,它会截取当前 RealityKit 场景的 3D 快照并加载到 Xcode 中。加载后你会看到:左侧是 Entity Hierarchy 树状结构,中间是 3D 视口,右侧是 Inspector 面板(显示选中 Entity 的属性和 Component)。

Session 用四个实际的 bug 场景演示了调试器的威力:变换继承导致的形状变形、Component 配置错误导致的行为异常、渲染管线配置错误导致的内容缺失,以及性能问题的定位方法。每个场景都是 3D 开发中最常见的头疼问题,而且没有这个工具之前都只能靠 log 和经验来猜。

值得深挖的点

Transform 继承:3D 开发最常见的坑

Session 的第一个 bug 是一个变形的迪斯科球。球体看起来被压扁了,但代码里迪斯科球本身的 scale 是 (1, 1, 1)——那变形从哪来的?

答案在 Entity Hierarchy 里。RealityKit 的 Transform 是继承的:一个 Entity 的最终位置、旋转、缩放是自己和所有祖先 Transform 的累积效果。迪斯科球的父 Entity “Support” 有一个 (1, 3, 1) 的缩放用来拉伸支架,但迪斯科球不幸是它的子节点,所以也被拉伸了。

用 RealityKit Debugger 的排查流程很清晰:在 3D 视口里双击选中变形的 Entity → Inspector 面板里看到它的 Transform 没问题 → 在 Hierarchy 里逐级向上查看父 Entity → 在 Support Entity 上发现了异常的 Y 轴缩放。修复方案也一目了然:把 Support 和 Background 从父子关系改成兄弟关系。

这个问题的教训是:在构建 Entity Hierarchy 时要特别注意”视觉上在一起”和”Transform 上是父子”的区别。Support 和 Background 视觉上连在一起,但它们不应该是父子关系,因为它们的 Transform 语义完全不同。

Component Inspector:找到行为异常的根源

第二个 bug 是传送器系统不工作——传送器存在但机器人不生成。排查方向是检查 TeleporterComponent 和 ControlCenterComponent 的数据是否正确配置。

过去你只能通过 print(entity.components) 来查看 Component 状态,输出一大堆原始数据很难阅读。RealityKit Debugger 的 Component Inspector 让你直接在可视化界面里检查每个 Component 的属性值——有没有 TeleporterComponent、countdown 值是多少、capacity 设置是多少,一目了然。

Session 还展示了 Entity Statistics Inspector,它会显示选中层级下的 Entity 数量、Component 类型统计等。这对于发现意外的 Entity 重复创建或 Component 重复添加非常有用。

代码片段

启动 RealityKit Debugger

// 不需要任何代码配置
// 在 Xcode 中运行你的 RealityKit App
// 点击调试栏底部的 "Capture Entity Hierarchy" 按钮
// (图标类似一个 3D 立方体 + 放大镜)
//
// 快捷方式:
// Debug Area > Capture Entity Hierarchy
//
// 截取后会在 Debug Navigator 中看到场景列表
// 点击场景即可进入 3D 检查模式

一句话说明:RealityKit Debugger 是零配置的,只要你用 RealityKit 框架运行 App,按钮就会出现在调试栏。截图只在暂停或运行时可用,不支持在 lldb 命令行里触发。

修复 Transform 继承问题

// 错误的 Hierarchy:Support → Background → DiscoBall
// Support 的 Y 轴缩放会继承到所有子节点
//
// 正确的 Hierarchy:
// Platform
//   ├── Support (scale: 1, 3, 1)  // 支架拉伸
//   ├── Background (scale: 1, 1, 1)  // 球体背景
//   └── Outline (scale: 1, 1, 1)  // 球体线条

let platform = Entity()
let support = Entity()
support.scale = SIMD3<Float>(1, 3, 1)  // 只影响支架自身

let background = Entity()  // 和 support 是兄弟关系
let discoBall = Entity()   // 不再被 support 的缩放影响

platform.addChild(support)
platform.addChild(background)
background.addChild(discoBall)

一句话说明:修复 Transform 继承问题的关键是理清”谁应该影响谁”。把视觉上相连但 Transform 语义不同的 Entity 设为兄弟而非父子。

检查 Component 配置

// 在 RealityKit Debugger 中检查 Component:
// 1. 在 Entity Hierarchy 中选中目标 Entity
// 2. Inspector 面板会列出所有已添加的 Component
// 3. 展开 Component 查看各属性值
//
// 常见检查项:
// - TeleporterComponent 是否存在?
// - ControlCenterComponent 的 countdown 值是否合理?
// - ModelComponent 的 mesh 和 material 是否正确?

// 也可以在代码中通过 Debugger 的信息验证
if let teleporter = entity.components[TeleporterComponent.self] {
    print("Teleporter capacity: \(teleporter.capacity)")
}

一句话说明:Debugger 里看到的 Component 值是运行时的真实值,不是代码里设置的初始值。如果你的 Component 在运行时被修改了,Debugger 会显示修改后的值。

最佳实践

新项目:把 RealityKit Debugger 纳入日常调试流程,就像你用 View Debugger 调试 UIKit 一样。每次遇到”内容显示不正常”的问题,第一反应应该是截取 Entity Hierarchy 而不是加 print。

已有项目:如果你有长期存在的”显示不正常但不知道为什么”的 bug,用 RealityKit Debugger 重新排查一遍。Session 里演示的 Transform 继承问题和 Component 配置错误都是那种”代码看起来没问题但就是不对”的典型场景,用可视化工具排查效率会高很多。

两个通用建议:第一,构建 Entity Hierarchy 时养成画树状图的习惯,确保 Transform 继承关系是你想要的,不要让视觉关系误导了层级关系。第二,给 Entity 取有意义的名字(name 属性),这样在 Debugger 的 Hierarchy 里才能快速定位到目标 Entity。

还有什么值得关注

  • Entity Statistics Inspector 可以帮你发现意外的 Entity 数量膨胀——如果你的场景里有几千个 Entity 但预期只有几十个,说明某个创建逻辑有 bug。
  • Debugger 的 3D 视口支持鼠标拖拽旋转、缩放、平移,可以自由选择观察角度。
  • 截取的快照是静态的,不会实时更新。如果需要观察动态变化,需要多次截取对比。
WWDC 2024