我正在寻找一种链接SceneKit动画的方式。
我要向场景中添加x个节点,我想添加第一个节点,使其淡入,一旦可见,我们便转到下一个节点,直到所有节点都可见。因此,在我们从第二个节点开始之前,我需要在第一个节点上结束动画。
很明显,我尝试使用SCNActions进行for循环,但是动画是批处理在一起的,因此所有节点都同时出现。
我不知道要添加多少个节点,因此无法进行序列化。
处理此问题的最佳方法是什么?
编辑:
好的,我发现如果在将序列添加到节点之前将其添加到暂停的场景中(包括增加的等待间隔)
let sequence = SCNAction.sequence([.wait(duration: delay), .fadeIn(duration: 0.5)])
node.runAction(sequence)
然后,一旦添加了所有节点,我便会取消暂停场景,从而达到我想要的效果。但这似乎很骇人。
有更好的方法吗?
答案 0 :(得分:1)
暂停/取消暂停-嗯,是的,但是如果您开始做更多的事情,那可能会引起问题。
我喜欢每个(James P)的completionHandler路由。您可以使用此方法设置多个(和不同的)动画或移动。就像移动到(5,0,0)一样,旋转,设置动画,当它到达那里时,再次调用它并移动到(10,0,0),依此类推。
如果它们都以相同的方式工作,则可以使用计时器,如果这正是您想要的,那将给您带来一定的一致性。如果您走这条路线,请确保在主线程中放置计时器。
您还可以根据需要创建一些预定义的序列:
let heartBeat = SCNAction.sequence([
SCNAction.move(to: SCNVector3(-0.5, 0.0, 0.80), duration: 0.4),
SCNAction.unhide(),
SCNAction.fadeIn(duration: 1.0),
SCNAction.move(to: SCNVector3(-0.3, 0.0, 0.80), duration: 0.4),
SCNAction.move(to: SCNVector3(-0.2, 0.2, 0.80), duration: 0.4),
SCNAction.move(to: SCNVector3(-0.1, -0.2, 0.80), duration: 0.4),
SCNAction.move(to: SCNVector3( 0.0, 0.0, 0.80), duration: 0.4),
SCNAction.move(to: SCNVector3( 0.1, 0.5, 0.80), duration: 0.4),
SCNAction.move(to: SCNVector3( 0.3, -0.5, 0.80), duration: 0.4),
SCNAction.move(to: SCNVector3( 0.5, 0.0, 0.80), duration: 0.4),
SCNAction.fadeOut(duration: 0.1),
SCNAction.hide()
])
node.runAction(SCNAction.repeatForever(heartBeat))
答案 1 :(得分:0)
我最终使用了Timer,我确实考虑了一下,但是无法使它正常工作,可能是因为我没有在主线程上这样做。
这是到目前为止我正在使用的代码,以防其他人在同一条船上。
func animateNodesInTo(scene: SCNScene, withDuration: TimeInterval) {
DispatchQueue.main.async {
let nodes = scene.rootNode.childNodes
let acion = SCNAction.fadeIn(duration: withDuration)
Timer.scheduledTimer(withTimeInterval: 1.0, repeats: true) { timer in
let opaqueNode = nodes.first(where: {$0.opacity == 0})
opaqueNode?.runAction(acion)
if opaqueNode == nil {
timer.invalidate()
}
}
}
}