2016-12-13 103 views
4

我有一个动态创建SCNView的视图。它的场景是空的,但是当我按下一个按钮时,我想从单独的scn文件中添加一个节点。这个文件包含动画,我希望它在主场景中动画。问题在于,在向场景添加对象之后,它不具有动画效果。当我将这个文件作为SCNView场景使用时。 isPlaying和循环已启用。我还需要做什么才能导入带有动画的节点?下面的示例代码:SceneKit从独立scn文件加载节点的动画

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) 


} 
+0

与你同样的问题,你解决了吗? – ooOlly

回答

3

您需要从场景Serah_Animated.scn,这将是一个CAAnimation对象获取动画。然后,将该动画对象添加到主场景的根节点。

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

您可以从.scn文件中使用Xcode中的场景编辑器,找到animID,如下图所示。

SceneKit AnimationID from the Xcode Scene Editor

现在可以将动画对象添加到您的根节点。

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

请注意,我们正在重新使用animID,这将允许您从节点中删除动画。上述

scene.rootNode.removeAnimation(forKey:<<animId>>) 
  • 我的解决方案假定您的动画是一个动画。如果看到一堆动画,则需要添加所有动画节点。在我的工作流程中,我将Blender中的文件导出为Collada格式,然后使用Automated Collada Converter确保我有单个动画节点。
  • Related SO answer
  • 您也可以获取animID编程方式使用entriesWithIdentifiersOfClass(CAAnimation.self),有用的,当你有一大堆的动画,而不是一个单一的动画如上或者如果你只是想添加动画,而不理会的animID前手。
  • Apple Sample Code for scene kit animations,请注意示例代码位于ObjC中,但翻译为Swift应该是直截了当的。
+2

我在.scn文件中没有找到实体列表。它只存在于.dae文件 – ooOlly

4

所有你需要的是检索动画:

 [childNode enumerateChildNodesUsingBlock:^(SCNNode *child, BOOL *stop) { 
     for(NSString *key in child.animationKeys) {    // for every animation key 
      CAAnimation *animation = [child animationForKey:key]; // get the animation 
      animation.usesSceneTimeBase = NO;      // make it system time based 
      animation.repeatCount = FLT_MAX;      // make it repeat forever 
      [child addAnimation:animation forKey:key];   // animations are copied upon addition, so we have to replace the previous animation 
     } 
    }]; 
+0

谢谢@ooOlly。 –