You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在RealityKit中将实体附着到骨骼关节并同步动画?

在RealityKit中实现关节附着子实体同步动画的问题

在SceneKit中,所有关节都是可添加子节点的独立节点,能直接同步父节点动画。我希望在RealityKit中实现相同效果:

  • 父模型仅显示5个子实体,不包含动画所用关节,但具备正确的关节名称与变换信息
  • 需要将独立的剑实体附着到手关节,使其跟随挥剑动画移动

我当前的代码打印平移数据显示剑随父节点移动,但屏幕上的位置与实际关节轨迹不符,这种实现方式是否推荐?SceneKit中只需将SCNNode添加到关节的SCNNode即可,RealityKit有没有更简便的方法?

原代码如下:

let playerModel = try! Entity.load(named: "Idle_Normal_SingleSword").findEntity(named: "root") as! ModelEntity
playerModel.scale = SIMD3<Float>(x: 0.01, y: 0.01, z: 0.01)

let swordAnchor = AnchorEntity()
let swordModel = try! Entity.load(named: "OHS08_Sword").findEntity(named: "OHS08_Sword_R_geometry") as! ModelEntity
swordModel.scale = SIMD3<Float>(x: 0.01, y: 0.01, z: 0.01)
swordModel.orientation = simd_quatf(angle: Float(90.radians), axis: [1, 0, 0])

swordAnchor.addChild(swordModel)

initialScene.addChild(playerModel)
playerModel.addChild(swordAnchor)

let handJointIndex = playerModel.jointNames.firstIndex {
    $0.contains("hand_r")
}
$0.scene.subscribe(to: SceneEvents.Update.self) { _ in
    swordModel.transform.translation = playerModel.jointTransforms[handJointIndex!].translation
}
.store(in: &cancellables)

正确实现方式:利用JointEntity绑定关节

RealityKit提供了更简便的关节绑定方案,无需手动每帧更新变换,步骤如下:

  1. 直接通过ModelEntity的joint(named:)方法获取目标关节的JointEntity
  2. 调整剑的本地变换,适配关节的初始姿态(位置偏移、旋转角度等)
  3. 将剑实体直接作为子节点添加到关节Entity下,自动跟随关节动画

修改后的代码:

// 加载并初始化玩家模型
let playerModel = try! Entity.load(named: "Idle_Normal_SingleSword").findEntity(named: "root") as! ModelEntity
playerModel.scale = SIMD3<Float>(x: 0.01, y: 0.01, z: 0.01)

// 加载并初始化剑模型
let swordModel = try! Entity.load(named: "OHS08_Sword").findEntity(named: "OHS08_Sword_R_geometry") as! ModelEntity
swordModel.scale = SIMD3<Float>(x: 0.01, y: 0.01, z: 0.01)

// 调整剑的初始姿态(根据模型实际情况修改偏移和旋转)
swordModel.transform = Transform(
    translation: [0.05, 0, 0],
    rotation: simd_quatf(angle: Float(90.radians), axis: [1, 0, 0]),
    scale: swordModel.scale
)

// 获取右手关节Entity
guard let rightHandJoint = playerModel.joint(named: "hand_r") else {
    fatalError("未找到右手关节")
}

// 将剑绑定到关节
rightHandJoint.addChild(swordModel)

// 将玩家模型加入场景
initialScene.addChild(playerModel)

原代码问题分析

  1. 仅同步平移,忽略旋转/缩放:关节动画包含完整的变换信息(平移+旋转+缩放),原代码只更新平移会导致剑的姿态完全错位
  2. 多余的中间层:swordAnchor是不必要的实体,增加了层级复杂度
  3. 手动更新效率低:通过SceneEvents.Update每帧更新变换,不仅性能不如内置绑定,还可能出现帧延迟导致的错位

内容的提问来源于stack exchange,提问作者ches

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.15 15:33:18