swiftscenekitcaanimation

Swift - SCNAnimationPlayer setting duration cancels out timeOffset


I have an animation that I'm trying to start & end at specific places. I can set the start by setting the animationPlayer.animation.timeOffset, I'm also trying to set the animation to end about 20s after the timeOffset & I can do that by setting animationPlayer.animation.duration.

The problem that I'm facing is that setting the duration cancels out the timeOffset. If I use just .timeOffset I can get the animation to start from any position but as soon as duration is set the animation will play from the beginning.

The intended result would be this: The animation starts at 25s (timeOffset) runs for 20s (duration) & then loops back to the timeOffset.

let rootNode = sceneView.rootNode
    
    rootNode.enumerateChildNodes { child, _ in
        guard let animationPlayer = child.animationPlayer(forKey: key) else { return }
        animationPlayer.animation.timeOffset = 25
        animationPlayer.animation.duration = 20
        animationPlayer.animation.autoreverses = true
        animationPlayer.animation.isRemovedOnCompletion = false
    }

Solution

  • The best solution I have found is something like this:

    let player = model.animationPlayer(forKey: "all")
    let animation = player?.animation
    func restartAnimation(atTimeOffset timeOffset: TimeInterval, duration: TimeInterval) {
        animation?.timeOffset = timeOffset
        if isWalking {
            player?.play()
            let uuid = isWalkingUUID
            DispatchQueue.main.asyncAfter(deadline: .now() + duration) {
                guard uuid == self.isWalkingUUID else { return }
                player?.stop(withBlendOutDuration: 0.2)
                restartAnimation(atTimeOffset: timeOffset, duration: duration)
            }
        } else {
            player?.stop(withBlendOutDuration: 0.2)
        }
    }
    restartAnimation(atTimeOffset: 33, duration: 0.6)