Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

SceneKit load node with animation from separate scn file

I have a view that creates SCNView dynamically. It's scene is empty, but when I press a button I would like to add a node from separate scn file. This file contains animation, and I would like it to animate in main scene. The problem is that after adding object to the scene it's not animating. When I use this file as SCNView scene it works. isPlaying and loops are enabled. What else do I need to do to import such node with animation? Sample code below:

override func viewDidLoad() {
    super.viewDidLoad()

    let scene = SCNScene()
    let sceneView = SCNView(frame: CGRect(x: 0, y: 0, width: 300, height: 300))
    sceneView.scene = scene
    sceneView.loops = true
    sceneView.isPlaying = true
    sceneView.autoenablesDefaultLighting = true
    view.addSubview(sceneView)


    let subNodeScene = SCNScene(named: "Serah_Animated.scn")!
    let serah = subNodeScene.rootNode.childNode(withName: "main", recursively: false)!

    scene.rootNode.addChildNode(serah)


}
like image 424
Damian Dudycz Avatar asked Dec 13 '16 20:12

Damian Dudycz


1 Answers

You need to fetch the animation from your scene Serah_Animated.scn, which will be a CAAnimation object. You then add that animation object to the rootNode of your main scene.

let animScene = SCNSceneSource(url:<<URL to your scene file", options:<<Scene Loading Options>>)
let animation:CAAnimation = animScene.entryWithIdentifier(<<animID>>, withClass:CAAnimation.self)

You can find the animID from the .scn file using scene editor in Xcode, as shown below.

SceneKit AnimationID from the Xcode Scene Editor

Now you can add the animation object to your root node.

scene.rootNode.addAnimation(animation, forKey:<<animID>>)

Note that we are reusing animID, that will allow you to also remove the animation from the node.

scene.rootNode.removeAnimation(forKey:<<animId>>)
  • My solution above assumes your animation is a single animation. If you see a bunch of animations, you need to add all the animation nodes. In my workflow, I have files in Blender which I export to Collada format and then use the Automated Collada Converter to ensure I have single animation nodes.
  • Related SO answer
  • You can also fetch the animID programmatically using entriesWithIdentifiersOfClass(CAAnimation.self), useful when you have a bunch of animations instead of a single animation as above or if you just want to add the animation without bothering about the animID before hand.
  • Apple Sample Code for scene kit animations, note the sample code is in ObjC but translation to Swift should be straight forward.
like image 124
3d-indiana-jones Avatar answered Nov 14 '22 21:11

3d-indiana-jones