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

如何在RealityKit中实现USDZ实体动画的反向播放?

如何在RealityKit中反向播放USDZ实体动画?

我尝试了如同在SceneKit中设置负速度的方式来实现动画反向播放,但并未生效。当前点击实体可正常触发第一次开门动画,但第二次点击无法通过反向动画实现关门效果。

以下是我的实现代码:

import SwiftUI
import RealityKit

struct ImmersiveView: View {
    @State var entity = Entity()
    @State var openDoor: Bool = true
    
    var body: some View {
        RealityView { content in
            if let mainDoor = try? await Entity(named: "Door.usdz") {
                
                if let frame = mainDoor.findEntity(named: "DoorFrame")
                {

                    frame.position = [0, 0, -8]

                    frame.orientation = simd_quatf(angle: (270 * (.pi / 180)), axis: SIMD3(x: 1, y: 0, z: 0))
                    
                    content.add(frame)
                    
                    entity = frame.findEntity(named: "Door")!
                    
                    entity.components.set(InputTargetComponent(allowedInputTypes: .indirect))
                    
                    entity.components.set(HoverEffectComponent())
                    
                    let entityModel = entity.children[0]
                    
                    entityModel.generateCollisionShapes(recursive: true)
                }
            }
        }
        .gesture(
            SpatialTapGesture()
                .targetedToEntity(entity)
                .onEnded { value in
                    print(value)
                    if openDoor == true
                    {
                        let animController = entity.playAnimation(entity.availableAnimations[0], transitionDuration: 0 , startsPaused: true)

                        animController.speed = 1.0
                        animController.resume()
                        
                        openDoor = false
                    }
                    else
                    {
                        let animController = entity.playAnimation(entity.availableAnimations[0], transitionDuration: 0 , startsPaused: true)
                        
                        animController.speed = -1.0 // 此设置无法实现反向播放
                        animController.resume()
                        
                        openDoor = true
                    }
                }
            )
    }
}

解决方案

RealityKit的AnimationController.speed属性不支持负值(这是和SceneKit的核心差异),所以直接设置speed = -1不会生效。你可以通过以下两种方式实现动画反向播放:

方式一:使用ReversedAnimation包装原动画

直接创建原动画的反向版本进行播放,代码修改如下:

.gesture(
    SpatialTapGesture()
        .targetedToEntity(entity)
        .onEnded { value in
            // 先停止当前动画,避免叠加冲突
            entity.stopAllAnimations()
            
            if openDoor {
                // 播放正向动画
                let forwardAnim = entity.availableAnimations[0]
                entity.playAnimation(forwardAnim, transitionDuration: 0)
                openDoor = false
            } else {
                // 创建并播放反向动画
                let reversedAnim = entity.availableAnimations[0].reversed()
                entity.playAnimation(reversedAnim, transitionDuration: 0)
                openDoor = true
            }
        }
)

方式二:通过playbackRange控制播放区间

设置动画的播放范围从结束点到起始点,配合正向速度实现反向效果:

.gesture(
    SpatialTapGesture()
        .targetedToEntity(entity)
        .onEnded { value in
            // 停止当前动画
            entity.stopAllAnimations()
            
            if openDoor {
                let controller = entity.playAnimation(entity.availableAnimations[0], transitionDuration: 0, startsPaused: true)
                controller.playbackRange = 0...1 // 正向区间:从开始到结束
                controller.speed = 1
                controller.resume()
                openDoor = false
            } else {
                let controller = entity.playAnimation(entity.availableAnimations[0], transitionDuration: 0, startsPaused: true)
                controller.playbackRange = 1...0 // 反向区间:从结束到开始
                controller.speed = 1
                controller.resume()
                openDoor = true
            }
        }
)

两种方式都能实现关门的反向动画效果,推荐第一种方式,代码更简洁直观。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.29 17:42:20