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

如何修改RealityKit中运行的OrbitAnimation的Transform实现轨道缓慢拓宽?

实现OrbitAnimation运行中动态拓宽轨道的方法

要在OrbitAnimation运行过程中不停止动画,实现轨道缓慢拓宽(y轴偏移从1到2),核心思路是叠加两个独立动画:一个负责维持环绕运动,另一个专门逐步修改y轴偏移量,让两者效果同步生效。

方案一:叠加动画实现(推荐)

利用RealityKit的动画叠加能力,同时运行环绕动画和轨道拓宽动画,两者互不干扰且效果自动合并:

func startAnimation() {
    DispatchQueue.main.asyncAfter(deadline: .now() + 1.0) {
        // 1. 创建持续运行的环绕动画
        let orbit = OrbitAnimation(duration: 10, axis: [0, 1, -5], 
                                  startTransform: Transform(translation: [0, 1, 0]), 
                                  bindTarget: .transform, repeatMode: .repeat)
        let orbitAnimation = try! AnimationResource.generate(with: orbit)
        
        // 2. 创建轨道拓宽动画:y轴偏移从1过渡到2,时长可按需调整
        let expandAnimation = try! AnimationResource.generate(with: BasicAnimation(
            path: \.transform.translation.y,
            from: 1,
            to: 2,
            duration: 8 // 比如8秒完成拓宽,和环绕动画周期配合
        ))
        
        // 3. 叠加播放两个动画,避免互相覆盖
        dragonSphere!.addAnimation(orbitAnimation, forKey: "orbitAnimation")
        dragonSphere!.addAnimation(expandAnimation, forKey: "expandOrbitAnimation")
    }
}

关键说明:

  • 使用addAnimation(_:forKey:)而非playAnimation,确保两个动画同时运行、效果叠加
  • 环绕动画负责维持实体的轨道旋转(repeatMode: .repeat保证持续运行)
  • 拓宽动画仅针对transform.translation.y属性做线性过渡,精准控制轨道拓宽的速度和幅度

方案二:实时更新Transform(备选)

如果需要更灵活的进度控制,可通过CADisplayLink每帧计算并更新y轴偏移值,注意需保留环绕动画的旋转效果:

var displayLink: CADisplayLink?
var elapsedTime: TimeInterval = 0
let totalExpandDuration: TimeInterval = 8 // 拓宽总时长
let startY: Float = 1
let endY: Float = 2

func startAnimation() {
    DispatchQueue.main.asyncAfter(deadline: .now() + 1.0) {
        // 启动环绕动画
        let orbit = OrbitAnimation(duration: 10, axis: [0, 1, -5], 
                                  startTransform: Transform(translation: [0, self.startY, 0]), 
                                  bindTarget: .transform, repeatMode: .repeat)
        let orbitAnimation = try! AnimationResource.generate(with: orbit)
        self.dragonSphere!.playAnimation(orbitAnimation)
        
        // 启动实时更新的DisplayLink
        self.elapsedTime = 0
        self.displayLink = CADisplayLink(target: self, selector: #selector(self.updateOrbitYOffset))
        self.displayLink?.add(to: .main, forMode: .common)
    }
}

@objc private func updateOrbitYOffset() {
    guard let link = displayLink else { return }
    elapsedTime += link.duration
    
    // 完成拓宽后停止更新
    if elapsedTime >= totalExpandDuration {
        link.invalidate()
        displayLink = nil
        return
    }
    
    // 计算当前y偏移的线性插值
    let progress = Float(elapsedTime / totalExpandDuration)
    let currentY = startY + (endY - startY) * progress
    
    // 更新transform,保留环绕动画的旋转部分
    var currentTransform = dragonSphere!.transform
    currentTransform.translation.y = currentY
    dragonSphere!.transform = currentTransform
}

注意事项:

  • 直接修改transform时,RealityKit会自动合并动画产生的变换与手动设置的偏移,不会打断环绕动画
  • 该方案适合需要动态调整拓宽节奏(比如根据交互改变速度)的场景

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.29 22:30:55