如何通过Swift代码获取并控制Reality Composer中的USDZ模型动画?
解决RealityKit中无法获取USDZ动画的问题
常见原因及解决方案
1. 动画可能嵌套在子实体中,而非根实体
USDZ模型的动画经常会挂载在深层子实体上,直接访问根实体的availableAnimations自然拿不到。可以通过遍历实体树的方式查找所有动画:
func collectAllAnimations(from entity: Entity) -> [AnimationResource] { var animations = entity.availableAnimations for child in entity.children { animations.append(contentsOf: collectAllAnimations(from: child)) } return animations } // 使用示例 if let rootModel = yourAnchorEntity.children.first as? ModelEntity { let allAnimations = collectAllAnimations(from: rootModel) print("共找到\(allAnimations.count)个动画") if let targetAnim = allAnimations.first { rootModel.playAnimation(targetAnim, transitionDuration: 0.3) } }
2. 检查USDZ的动画结构是否兼容RealityKit
Reality Converter导出的部分USDZ会用SCNAnimation兼容结构包装动画,此时可以直接从文件URL加载实体,避免中间封装导致的丢失:
guard let modelUrl = Bundle.main.url(forResource: "YourAnimatedModel", withExtension: "usdz") else { return } do { let assetEntity = try Entity.load(contentsOf: modelUrl) // 遍历实体树查找动画 assetEntity.visit { entity in if !entity.availableAnimations.isEmpty { print("找到动画:\(entity.availableAnimations.map{ $0.name })") entity.playAnimation(entity.availableAnimations[0]) } } yourAnchorEntity.addChild(assetEntity) } catch { print("加载模型失败:\(error)") }
3. 不要依赖Reality Composer封装的动画逻辑
如果是在Reality Composer里给模型加了触发动画,这些动画会被封装在行为模板中,不会直接出现在实体的availableAnimations里。建议直接导入原始USDZ文件,而非Reality Composer导出的.reality或.rcproject文件,保留动画的原始挂载结构。
4. 无需纠结definition为空,直接用name或实例播放
部分USDZ动画的definition字段确实会显示为空,但只要availableAnimations里存在实例,就可以直接调用playAnimation播放。可以打印动画名称确认存在:
if let firstAnim = entity.availableAnimations.first { print("动画名称:\(firstAnim.name ?? "未命名")") entity.playAnimation(firstAnim) }
内容的提问来源于stack exchange,提问作者Cyan010320
相关产品推荐
相关产品推荐

