![](/img/trans.png)
[英]How to split out multiple animations from Collada file in SceneKit
[英]Multiple serial animations in SceneKit
我希望能夠在SceneKit中一個接一個地運行多個動畫。 我已經實現了一個運行一個動畫的函數:
fileprivate func animateMove(_ move: Move) {
print("Animate move started " + move.identifier)
// I am creating rotateNode
let rotateNode = SCNNode()
rotateNode.eulerAngles.x = CGFloat.pi
scene.rootNode.addChildNode(rotateNode)
// Then I am selecting nodes which I want to rotate
nodesToRotate = ...
// Then I am adding the nodes to rotate node
_ = nodesToRotate.map { rotateNode.addChildNode($0) }
SCNTransaction.begin()
SCNTransaction.animationDuration = move.animationDuration
SCNTransaction.completionBlock = {
rotateNode.enumerateChildNodes { node, _ in
node.transform = node.worldTransform
node.removeFromParentNode()
scene.rootNode.addChildNode(node)
}
rotateNode.removeFromParentNode()
print("Animate move finished " + move.identifier)
}
SCNTransaction.commit()
}
然后我嘗試運行多個串行動畫,如下所示:
func animateMoves(_ moves: [Move]) {
for (index, move) in moves.enumerated() {
perform(#selector(animateMove(_:)),
with: move,
afterDelay: TimeInterval(Double(index) * move.duration)
}
}
一切都是動畫,但動畫不是以連續的方式運行。 動畫在不可預測的時間內開始和結束。 來自調試器的示例日志:
Animate move started 1
Animate move started 2
Animate move finished 1
Animate move finished 2
Animate move started 3
Animate move finished 3
我意識到我的方法不是最好的,但只有通過這種方式,我才能實現幾乎可以工作的動畫。
我知道有一個SCNAction類可用。 也許我應該在一次交易中做出很多動作? 如果是這樣,有人可以向我解釋SCNTransactions究竟是如何工作的以及SCNTransaction的完成塊在不可預測的時間內完成的原因是什么?
嘗試使用SCNAction.sequence() :
class func sequence([SCNAction])
創建一個按順序運行操作集合的操作
let sequence = SCNAction.sequence([action1, action2, action3]) // will be executed one by one
let node = SCNNode()
node.runAction(sequence, completionHandler:nil)
按照@Oleh Zayats的回答我試圖使用SCNAction.sequence(_ :)方法實現我的案例,但問題是我需要在每個完成的子操作之后觸發完成處理程序,以便能夠從中刪除節點rotationNode。
經過幾個小時的掙扎,我得到了一個非常好的解決方案,它就像一個魅力。
即:
我做了一個函數rotateAction,它看起來像這樣:
func rotateAction(with move: Move, from rotateNode: SCNNode) -> SCNAction {
let preAction = SCNAction.run { (rotateNode) in
// all the pre action setup like choosing nodes to rotate
}
let action = SCNAction.rotate(by: -move.angle, around: vector, duration: move.animationDuration)
let postAction = SCNAction.run { (rotateNode) in
// completion handler for each action
}
return SCNAction.sequence([preAction, action, postAction])
}
然后我能夠編寫一個函數,以便能夠一個接一個地運行多個動畫:
func animateRotateMoves(_ moves: [Move]) {
let rotateNode = SCNNode()
scene.rootNode.addChildNode(rotateNode)
var actions: [SCNAction] = []
for move in moves {
let action = rotateAction(with: move, from: rotateNode)
actions.append(action)
}
actions.append(SCNAction.removeFromParentNode())
let sequence = SCNAction.sequence(actions)
rotateNode.runAction(sequence)
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.