キービットは、私はこれらが、私はCAAnimationGroupを使うと、「作物」のフルアニメーションを使用することができた後は
CAAnimation(scnAnimation: animation)
と
SCNAnimation(caAnimation: animation)
を見つけることでした。
ここに私が取り組んでいた私のTroll.swiftがあります。もちろん、やりたいことはたくさんありますが、少なくとも私は貧しい獣を散歩させて死ぬことができます。
class Troll: SCNNode {
var body:SCNNode!
static func timeRange(forStartingAtFrame start:Int, endingAtFrame end:Int, fps:Double = 30) -> (offset:TimeInterval, duration:TimeInterval) {
let startTime = self.time(atFrame: start, fps: fps) //TimeInterval(start)/fps
let endTime = self.time(atFrame: end, fps: fps) //TimeInterval(end)/fps
return (offset:startTime, duration:endTime - startTime)
}
static func time(atFrame frame:Int, fps:Double = 30) -> TimeInterval {
return TimeInterval(frame)/fps
}
static func animation(from full:CAAnimation, startingAtFrame start:Int, endingAtFrame end:Int, fps:Double = 30) -> CAAnimation {
let range = self.timeRange(forStartingAtFrame: start, endingAtFrame: end, fps: fps)
let animation = CAAnimationGroup()
let sub = full.copy() as! CAAnimation
sub.timeOffset = range.offset
animation.animations = [sub]
animation.duration = range.duration
return animation
}
func load() {
guard let trollScene = SCNScene(named: "Models.scnassets/troll/troll.dae") else {
fatalError("Can't load the scene")
}
guard let troll_body = trollScene.rootNode.childNode(withName: "troll", recursively: true) else {
fatalError("found no troll")
}
guard let troll_weapon = trollScene.rootNode.childNode(withName: "troll_weapon", recursively: true) else {
fatalError("found no troll_weapon")
}
guard let troll_bracelet = trollScene.rootNode.childNode(withName: "troll_bracelet", recursively: true) else {
fatalError("found no troll_bracelet")
}
guard let bips = trollScene.rootNode.childNode(withName: "Bip01", recursively: true) else {
fatalError("found no Bip01")
}
guard let fullKey = bips.animationKeys.first else {
fatalError("Bip01 got no animation")
}
guard let fullPlayer = bips.animationPlayer(forKey: fullKey) else {
fatalError("Bip01 got no player for \(fullKey)")
}
let fullAnimation = CAAnimation(scnAnimation: fullPlayer.animation)
self.addChildNode(troll_body)
self.addChildNode(troll_weapon)
self.addChildNode(troll_bracelet)
self.addChildNode(bips)
self.body = bips
self.body.removeAllAnimations()
let walkAnimation = Troll.animation(from: fullAnimation, startingAtFrame: 10, endingAtFrame: 60)
walkAnimation.repeatCount = .greatestFiniteMagnitude
walkAnimation.fadeInDuration = 0.3
walkAnimation.fadeOutDuration = 0.3
let walkPlayer = SCNAnimationPlayer(animation: SCNAnimation(caAnimation: walkAnimation))
self.body.addAnimationPlayer(walkPlayer, forKey: "walk")
let deathAnimation = Troll.animation(from: fullAnimation, startingAtFrame: 1810, endingAtFrame: 1850)
deathAnimation.isRemovedOnCompletion = false
deathAnimation.fadeInDuration = 0.3
deathAnimation.fadeOutDuration = 0.3
let deathPlayer = SCNAnimationPlayer(animation: SCNAnimation(caAnimation: deathAnimation))
self.body.addAnimationPlayer(deathPlayer, forKey: "death")
self.scale = SCNVector3(0.1,0.1,0.1)
}
func walk() {
print("+++ walk +++")
self.body.animationPlayer(forKey: "walk")?.play()
}
func death() {
print("+++ death +++")
self.body.animationPlayer(forKey: "walk")?.stop(withBlendOutDuration: 0.3)
self.body.animationPlayer(forKey: "death")?.play()
}
}
animationPlayer(forKey :)は、タイプCAKeyframeAnimationのアニメーションを含むCAAnimationGroupを返します。配列の値とkeyTimesを置き換えてアニメーションをトリミングし、keyTimesをシフトしてすぐに開始させることができます。残念ながら、animationPlayer(forKey :)はiOS11では廃止され、結果を操作することで新たに "未定義の動作が発生する"という結果になります。これはkeyPathを消去します。あなたの操作の前にキャッシングして置き換えることで、そのバグを回避してください。私はまだSCNAnimationPlayerがanimationPlayer(forKey :)に基づく変更をどのように置き換えることができないのか誰かが知りたがっています。 – pommy
はい。私はいつかXcode 8のコードを使って遊んだり、CAAnimationGroupsはうまく動作しています...私はXcode 9のアイデアを持っています...少し実験します:) – AutomatonTec