节点组的位置在SCNNode.runAction的开头重置

我有一些代码可以在屏幕被点击时围绕x轴旋转几个SCNNode:

func handleTap(gestureRecognize: UIGestureRecognizer) { let sceneView = self.view as SCNView let slice = self.cubes[0...8] let container = SCNNode() for node: SCNNode in slice { container.addChildNode(node) } sceneView.scene!.rootNode.addChildNode(container) container.runAction(SCNAction.rotateByX(CGFloat(M_PI / 2), y: 0.0, z: 0.0, duration: 1), completionHandler: { () -> Void in println("complete") }) } 

我遇到的问题是,每次调用此函数时,节点似乎都会在执行操作之前将自身重置为原始位置。 操作完成后,它们似乎保持在正确的位置,直到再次点击屏幕。 如何进行后续调用handleTap将它们从当前位置旋转?

我尝试在将节点添加到容器之前从其原始父节点中删除节点,但它没有可见的效果。

我也试过用动画

  let spin = CABasicAnimation(keyPath: "rotation") spin.fromValue = NSValue(SCNVector4: SCNVector4(x: -1, y: 0, z: 0, w: 0)) spin.toValue = NSValue(SCNVector4: SCNVector4(x: -1, y: 0, z: 0, w: Float(M_PI_2))) spin.duration = 3 spin.repeatCount = .infinity container.addAnimation(spin, forKey: "spin around") 

其效果与动作完全相同。

如果我将节点作为根视图的子节点放回runAction的完整块中

  container.runAction(action, completionHandler: { () -> Void in println("completed rotation") for node: SCNNode in slice { node.removeFromParentNode() sceneView.scene!.rootNode.addChildNode(node) } }) 

然后,节点在完成操作时返回到其原始位置,而不是在新点击的开始处。

从场景的根节点中删除节点,添加到容器并旋转时,将相对于容器的本地坐标系将变换应用于节点。 解决方案是将节点的变换从容器的坐标系转换为根节点的坐标系,然后再将其添加回根节点。

 func handleTap(gestureRecognize: UIGestureRecognizer) { let sceneView = self.view as SCNView let action = SCNAction.rotateByAngle(CGFloat(M_PI_2), aroundAxis: SCNVector3Make(-1, 0, 0), duration: 1) let slice = self.cubes[0...8] let container = SCNNode() let root = sceneView.scene!.rootNode for node: SCNNode in slice { container.addChildNode(node) } root.addChildNode(container) container.runAction(action, completionHandler: { () -> Void in for node: SCNNode in slice { let transform = node.parentNode!.convertTransform(node.transform, toNode: root) node.removeFromParentNode() node.transform = transform root.addChildNode(node) } }) }