Compose interactive 3D content in Reality Composer Pro
System Frameworks 进阶 20m

在 Reality Composer Pro 中编排交互式 3D 内容

Compose interactive 3D content in Reality Composer Pro

2024年6月10日

在 Apple 官方观看视频

一句话判断

Reality Composer Pro 今年新增了 Timelines 编辑器——一个可视化的动画编排工具,让你不用写代码就能串起旋转、移动、动画播放、音频触发等动作序列,而且编排结果可以在代码中通过触发器精确控制播放时机。

这场 Session 讲了什么

这场 Session 由 RealityKit Tools 工程师 Marin 主讲,核心是介绍 Reality Composer Pro 的全新 Timelines 功能。以一个机器人浇花的交互式 App(Botanist 样例的扩展版)贯穿全场。

Timelines 是一个序列化动作编排系统。你可以在 Reality Composer Pro 里创建多个 Timeline,每个 Timeline 包含一系列按时间排列的 action。可用的 action 包括 Spin(旋转)、Transform To(移动到目标位置)、Animation(播放预置骨骼动画)、Audio(播放音效)等。

Session 的演示流程很完整:先用 Spin + Transform To 让机器人转向并移动到植物前,然后用 AnimationLibraryComponent 和 AudioLibraryComponent 让它在移动时播放行走动画和脚步声。接着用代码触发 Timeline 播放,用 RealityKit 的 Full Body IK 让机器人伸手浇花。最后演示了 blend shape 动画让植物从枯萎恢复到健康,以及骨骼动画让第二个机器人追逐蝴蝶。

值得深挖的点

Timelines 的设计哲学:可视化编排 + 代码触发

Timelines 的核心理念是把”动画做什么”和”动画什么时候播”分离。动画师在 Reality Composer Pro 里用拖拽的方式编排动作序列、调整时序、预览效果。开发者在代码里决定何时触发哪个 Timeline。

这个分离非常聪明。动画调整是最需要反复试错的环节——机器人转多少度看起来自然?移动速度多快不会显得突兀?这些都需要”看到才能判断”。过去这些参数写在代码里,每次调整都要重新编译运行。现在在编辑器里拖拽就能实时预览,确认效果后代码完全不需要改。

Timeline 的触发是通过 RealityKit 代码控制的。你可以在用户点击某个植物时调用 playTimeline("MoveToPoppy"),也可以在系统事件中触发。多个 Timeline 可以嵌套和协调——比如”移动到植物”的 Timeline 触发后,同时启动”行走动画 + 脚步声”的另一个 Timeline。

AnimationLibraryComponent 和 AudioLibraryComponent

这是两个新的组件,解决了”动画和音效资源怎么管理”的问题。过去你需要在代码里手动加载 USD 动画和音频文件,管理资源引用。现在你直接在 Reality Composer Pro 里把动画文件拖到 AnimationLibraryComponent 里、把音频文件拖到 AudioLibraryComponent 里,它们就跟 Entity 绑定了。

在 Timeline 里使用这些资源时,你只需要选择目标 Entity 和对应的动画/音效名称。编辑器会列出所有可用的资源供你选择。这种方式让美术人员和开发者的协作变得更流畅——美术在编辑器里调整动画,开发者在代码里只关心触发逻辑,互不干扰。

代码片段

在代码中触发 Timeline 播放

// 当用户点击植物时触发机器人移动
func onPlantTapped(_ plant: Entity) {
    // 获取机器人实体上的 Timeline 控制器
    guard let timeline = robot.components[TimelineComponent.self] else { return }

    // 根据 plant 类型选择对应的 Timeline
    let timelineName = "MoveTo\(plant.name)"
    timeline.play(timelineName)
}

一句话说明:Timeline 的播放完全由代码控制触发时机,编辑器只负责编排内容。你可以在任何用户交互或系统事件中触发 Timeline。

使用 Full Body Inverse Kinematics 让机器人伸手

// 配置 IK 目标:让机器人的手伸向植物
let ikSkeleton = robot.components[IKSkeletonComponent.self]

// 设置右手的 IK 目标位置为植物位置
var ikConstraint = IKConstraint()
ikConstraint.targetEntity = plantWaterLocation
ikConstraint.chainCount = .fullBody  // 使用全身 IK

// 应用 IK 约束
ikSkeleton?.setConstraint(ikConstraint, forJoint: "rightHand")

一句话说明:Full Body IK 让你不需要手动调整每个关节角度,只需要指定”手要去哪里”,系统自动计算合理的全身姿势。注意 chainCount 选择 .fullBody 时会考虑重心平衡。

在代码中播放 blend shape 动画让植物恢复

// 植物从枯萎到健康的 blend shape 动画
func animatePlantRecovery(_ plant: Entity) {
    guard let mesh = plant.components[ModelComponent.self]?.mesh else { return }

    // 从"枯萎"形状过渡到"健康"形状
    let blendShapeWeights = [0.0, 1.0]  // [wilt: 0, healthy: 1]

    let animation = try! AnimationResource.generateBlendShapeAnimation(
        name: "recovery",
        bindTarget: .blendShapeWeights,
        timeline: .linear(duration: 2.0),
        values: blendShapeWeights
    )

    plant.playAnimation(animation)
}

一句话说明:Blend shape 动画非常适合做表情、植物生长等”形状渐变”效果。generateBlendShapeAnimation 是 RealityKit 的程序化动画 API,不需要预制的 USD 动画文件。

最佳实践

新项目:把所有动画序列都在 Reality Composer Pro 的 Timelines 里编排好,代码只负责触发逻辑。这样美术调整动画时不需要动代码,开发者调整触发逻辑时不需要理解动画细节。AnimationLibraryComponent 和 AudioLibraryComponent 从一开始就用来管理资源。

已有项目:如果你的 App 已经有大量手写的动画代码,不需要全部迁移到 Timelines。可以先把新功能的动画用 Timelines 实现,逐步验证效果后再决定是否迁移旧代码。Timeline 和手写动画可以混合使用——比如用 Timeline 控制移动,用代码控制 IK。

还有什么值得关注

  • Timeline 支持多个 track 并行执行,你可以让机器人的移动和旋转同时进行而不会互相阻塞。
  • Transform To action 可以用 manipulator 在编辑器的 3D 视图里直接拖拽目标位置,所见即所得。
  • 新的骨骼动画 API 可以在代码里程序化生成简单的动画,适合那些不需要美术预制的循环动作。
WWDC 2024