在Swift 4中,我从数组中的dae文件加载/保存一组动画:
var animations = [String: CAAnimation]()
loadAnimation(withKey: "stepL", sceneName: "art.scnassets/StepL", animationIdentifier: "StepL-1")
loadAnimation(withKey: "stepR", sceneName: "art.scnassets/StepR", animationIdentifier: "StepR-1")
func loadAnimation(withKey: String, sceneName:String, animationIdentifier:String) {
let sceneURL = Bundle.main.url(forResource: sceneName, withExtension: "dae")
let sceneSource = SCNSceneSource(url: sceneURL!, options: nil)
if let animationObject = sceneSource?.entryWithIdentifier(animationIdentifier, withClass: CAAnimation.self) {
// The animation will only play once
animationObject.repeatCount = 1
// To create smooth transitions between animations
animationObject.fadeInDuration = CGFloat(0.8)
animationObject.fadeOutDuration = CGFloat(0.6)
// Store the animation for later use
animations[withKey] = animationObject
}
}
稍后我正在播放动画,将其添加到我的场景中:
func playAnimation(key: String) {
print("fire animation: " + key)
scnView.scene?.rootNode.addAnimation(animations[key]!, forKey: key)
}
这似乎可以在触摸时单独进行,但我希望能够以非常具体的时间触发这些序列。
我已经尝试构建一个循环并将其发送到具有特定时序的DispatchQueue:
var delaytime = state.steptime!
for _ in 0..<state.trCount! {
for wSide in state.walkSeq! {
walkQ.asyncAfter(deadline: .now() + delaytime){
self.playAnimation(key: wSide)
}
delaytime += state.steptime! + 1.0
}
}
我尝试过使用wallDeadline的类似但略有不同的方法:
let wt = DispatchWallTime.now() + state.pausetime!
//build sequence
var train_seq = [(name:"stepL", time:wt), (name:"stepR",time:wt + state.pausetime! + state.steptime!)]
for _ in 0..<state.trCount! {
let lasttime = train_seq[ train_seq.count - 1 ].time
train_seq += [(name:"stepL", time:lasttime + state.steptime!)]
train_seq += [(name:"stepR", time:lasttime + state.pausetime! + state.steptime!)]
}
//send it
for i in 0..<train_seq.count {
walkQ.asyncAfter(wallDeadline: train_seq[i].time){
self.playAnimation(key: train_seq[i].name)
}
}
不可避免地发生的是前几个按预期运行,然后围绕第四组序列开始叠加在一起并同时点火,不再遵守我定义的时间< / p>
在预期时间轴上触发序列中动画的最佳方法是什么?有没有办法暂停/睡眠循环,直到前一个动画停止,然后触发系列中的下一个?
谢谢!
答案 0 :(得分:0)
我最终按照我需要的顺序进行了一系列SCNAction,包括等待
var seq = [SCNAction]()
for _ in 0..<state.trCount!{
let act1 = SCNAction.run {_ in
self.playAnimation(key: "stepL")
}
seq.append(act1)
let act2 = SCNAction.wait(duration: state.steptime!)
seq.append(act2)
let act3 = SCNAction.run { _ in
self.playAnimation(key: "stepR")
}
seq.append(act3)
seq.append(act2)
let act4 = SCNAction.run { _ in
self.playAnimation(key: "idle")
}
seq.append(act4)
let act5 = SCNAction.wait(duration: state.pausetime!)
seq.append(act5)
}
let sequence = SCNAction.sequence(seq)
scnView.scene?.rootNode.runAction(sequence, completionHandler:nil )