有没有办法链接 SceneKit 动画?
Posted
技术标签:
【中文标题】有没有办法链接 SceneKit 动画?【英文标题】:Is there a way to chain SceneKit Animations? 【发布时间】:2020-01-19 21:56:17 【问题描述】:我正在寻找一种链接 SceneKit 动画的方法。
我正在向场景中添加 x 个节点,我想添加第一个节点,使其淡入,一旦它可见,然后我们转到下一个节点,直到所有节点都可见。所以我需要在我们开始第二个节点之前结束第一个节点上的动画。
显然,我尝试了一个带有 SCNActions 的 for 循环,但动画是批处理的,所以所有节点同时出现。
我不知道会添加多少节点,所以我无法制作序列。
处理此问题的最佳方法是什么?
编辑:
好的,我想如果我在将序列添加到暂停场景之前将其添加到节点(包括增加的等待间隔)
let sequence = SCNAction.sequence([.wait(duration: delay), .fadeIn(duration: 0.5)])
node.runAction(sequence)
然后,一旦添加了所有节点,我就会取消暂停场景,它会达到我正在寻找的效果。但这似乎很hacky。
有没有更好的办法?
【问题讨论】:
您可以将runAction
与在操作完成时调用的completionHandler
结合使用。那会有帮助吗? developer.apple.com/documentation/scenekit/scnactionable/…
【参考方案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))
【讨论】:
【参考方案2】:我最终使用了一个计时器,我确实考虑过这个但无法让它工作,可能是因为我没有在主线程上做。
这是我目前使用的代码,以防其他人在同一条船上。
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()
【讨论】:
以上是关于有没有办法链接 SceneKit 动画?的主要内容,如果未能解决你的问题,请参考以下文章
有没有办法在 SceneKit 的 Collada 文件中存储动画数据或任意数据?