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

RealityKit中连续执行FromToByAction动画未按预期工作的问题

RealityKit中连续执行FromToByAction动画未按预期工作的问题

看起来你遇到的问题是RealityKit里的连续动画延迟没生效,开门动画刚结束就直接触发关门了对吧?我之前在做类似交互时也踩过这个坑,咱们来一步步捋清楚问题出在哪,以及怎么解决。

首先得说清楚你当前代码的问题:你试图给关门动画加offset来实现停留,但在AnimationResource.sequence()的逻辑里,这个offset是相对于整个动画序列的起始时间,而不是前一个动画的结束时间。再加上你把关门动画的duration设置成了duration + stayingOpenFor,这其实是把关门动作本身的时长拉长了,根本不是你想要的“停留后再关门”的效果。

给你两个可行的解决方案,推荐第一个,逻辑更直观:

方案一:插入专门的等待动画(推荐)

RealityKit其实提供了纯等待的动画资源,你可以用AnimationResource.makeWait(duration:)生成一个不做任何动作的等待动画,把它插到开门和关门动画中间,让序列按「开门→等待→关门」的顺序执行。

修改后的代码如下:

func openSlider(duration: TimeInterval, stayingOpenFor: TimeInterval) {
    let closedPosition = Transform(translation: RKVector(DoorwaySegment.normalDoorWidth * -0.5, (WallUtilities.wallHeight - DoorwaySegment.normalDoorHeight) / -2.0, 0.0))
    let openPosition = Transform(translation: RKVector(DoorwaySegment.normalDoorWidth * -1.45, (WallUtilities.wallHeight - DoorwaySegment.normalDoorHeight) / -2.0, 0.0))
    
    do {
        // 开门动画:保持原有逻辑
        let openAction = FromToByAction<Transform>(from: closedPosition, to: openPosition)
        let openAnimation = try AnimationResource.makeActionAnimation(for: openAction, duration: duration, bindTarget: .transform)
        
        // 新增:创建指定时长的等待动画
        let waitAnimation = AnimationResource.makeWait(duration: stayingOpenFor)
        
        // 关门动画:恢复原本的duration,不需要叠加stayingOpenFor
        let closeAction = FromToByAction<Transform>(from: openPosition, to: closedPosition)
        let closeAnimation = try AnimationResource.makeActionAnimation(for: closeAction, duration: duration, bindTarget: .transform)
        
        // 按顺序拼接三个动画
        let concatenated = try AnimationResource.sequence(with: [openAnimation, waitAnimation, closeAnimation])
        // 如果需要监听整个序列完成,可以用带completionHandler的playAnimation方法
        door.playAnimation(concatenated, completionHandler: { finished in
            if finished {
                print("开门-等待-关门流程已完成")
            }
        })
    } catch {
        print("failed to open/shut door")
    }
}

这种方式的好处是每个动画的职责清晰,开门、等待、关门各自独立,后续要调整时长或者逻辑都非常方便,也不容易出错。

方案二:调整关门动画的offset和duration(不推荐)

如果你坚持想用offset的方式实现,那得调整参数逻辑:关门动画的offset应该设置为开门动画的时长 + 停留时长,同时关门动画的duration要保持原本的duration(不能叠加停留时间)。不过这种方式的逻辑比较绕,因为sequence里的动画是按顺序触发的,offset是相对于整个序列的起点,不是前一个动画的终点,所以很容易搞混,不如方案一直观。

最后再提两个小注意点:

  • 确保你的door实体没有其他正在运行的动画干扰它的transform属性,否则可能会出现预期外的行为
  • 如果你用的是旧版本的RealityKit,记得检查makeWait方法是否可用(这个方法是在iOS 15/macOS 12及以上版本引入的)

内容来源于stack exchange

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.07 13:19:51