0

I'm looking for a solution for my problem: I have defined a animation as SCNAction with the action editor in Xcode. Now I want to control it with a slider. So basically manipulating the slider shows a specific time/frame in the animation.

Right now, I can just pause/play the animation or reset it to the beginning. I achieved this with Swift code addressing the SCNAction from the action editor.

As far as I researched, there is no possibility to animate a SCNAction to a specific time immediately and stop right there. That would work.

I'm also interested in other attempts if this is not achievable with SCNActions. It may be that this is not realizable at all. Thank you.

Pineapple3D
  • 121
  • 1
  • 8
  • You can update the `SCNMatrix` on slider `didChange` where the slider value is used to calculate position. Then it will look like its animating to its position when sliding the slider – Vollan Apr 11 '18 at 15:04
  • But then the whole animation process itself gets way more complicated. The animation would be more like "configured" then and not "designed". Nevertheless, it is realizable in that way and probably while creating animations I would use both: the Action Editor and extracting values from there. Thank you for your idea. – Pineapple3D Apr 11 '18 at 15:27
  • there was a whole developer video on this but using UIKit. i just remember watching it but not the specific details, you might find something useful there - https://developer.apple.com/videos/play/wwdc2017/230/ – Mec Os Apr 11 '18 at 19:27

1 Answers1

0

I found a solution: I loaded a CAAnimation from a .dae file(For this look here:https://stackoverflow.com/a/24924702/9625548, bit outdated but still usable).

With the SCNAnimationPlayer I can address the CAAnimation with a key. With the following code I can control my animation with a UISlider:

let moment: TimeInterval = TimeInterval(self.animationTimeSlider.value)
guard let animationPlayer: SCNAnimationPlayer = node.animationPlayer(forKey: key) else{
                    return
                }
animationPlayer.animation.timeOffset = moment
animationPlayer.play()
animationPlayer.speed = 0.0

Basically, I read the thumb and convert it to TimerInterval. I'm looking for the SCNAnimationPlayer and aborting if no SCNAnimationPlayer is found for the given key. Then I set the .timeOffset to the moment I want to display. With play(), the animation starts from the beginning + .timeOffset. Finally, set the .speed to zero. the animation is not running but shows the moment.

Attention: If you let your animation running and also manipulating it in that way, you have to reset it. Otherwise it is getting messed up. You can catch that case with a boolean that saves if you let your animation run normally. Then you know you have to reset it before manipulating with the slider. For example like this:

node.removeAllAnimations() node.addAnimation(animation, forKey: key) self.sceneView.scene.rootNode.animationPlayer(forKey: key)?.paused = true

Pineapple3D
  • 121
  • 1
  • 8