SpriteKit で SKAction の sequence と group を同時に使う

swift

SpriteKit で SpriteNode などにアニメーション等の動作をさせたりするときに SKAction を使います。

この SKAction、複数の SKAction を組み合わせることができます。

直列に実行

1つの SKAction が終わったらすぐ次の SKAction を実行したいとき

SKAction.sequence([someAction1, someAction2])
並列に実行

2つの SKAction を同時に実行したいとき

SKAction.group([someAction3, someAction4])
直列/並列に実行

では、2つの SKAction.gruop を直列で実行したいときは?

let group1 = SKAction.group([someAction1, someAction2])
let group2 = SKAction.group([someAction3, someAction4])

let sequence = SKAction.sequence([gruop1, group2])

self.run(sequence)

とかやればいいわけです。

以下にも書かれています。

SpriteKitでのアニメーションまとめ – 2016年02月05日
https://qiita.com/sa-k0/items/c5be9e0912c11631bae1

期待通り動作しない場合

上記でうまくいかない場合もあります。

原因としては、someAction の中に SKAction.repeatForever が入っている場合等。

例えば、あるキャラクターが足踏みしているアニメーションを repeatForever で設定することが多いと思います。

この状態で、例えば、「左に3歩進んだ後に、上に5歩進む」といったアニメーションをしたい場合、

repeatForever を含む Action を切り替えたいのですが、 repeatForever が永久に終わらないため、次に進みません。

このような場合でも解決策があります。

SKAction の run メソッドには completion があるので、ここでアニメーションを切り替えて、また動く action を run すればいいのです。

run(_:completion:)
https://developer.apple.com/documentation/spritekit/sknode/1483103-run

雰囲気をつかんでいただきたいのですが、下記のように書けば動作します。

node.run(actionAnimationLeft)

node.run(actionsMoveLeft, completion: {
  node.run(actionAnimationRight)

  node.run(actionMoveRight, completion: {
    node.run(actionAnimationUp)

    node.run(actionMoveUp)
  })
})

ドラクエ3のオープニングで、お母さんが勇者を自動でお城に連れてってくれるシーンがありますが、そこで上記のコードが使われています。

dq3_ios – github
https://nomad.office-aship.info/dq3-ios

難点としては、このように書くと、どんどんネストが深くなっていくことでしょうか。

しかし、Xcode 13 で swift 5.5 による async/wait が導入されると、このようなネスト地獄が解消されると思います。

解消されたら、そちらのコードも載せていきたいと思います。

Swift 6 & 5.5 まとめ
https://nomad.office-aship.info/swift-6

Swift 関連書籍

SwiftUI開発レシピ iOS 14 対応

SwiftUI iPhoneアプリ開発入門ノート[2020] iOS 14 対応

SwiftUI 徹底入門

SwiftUIではじめるiPhoneアプリプログラミング入門

iOS/macOS UIフレームワーク SwiftUIプログラミング

コメント

タイトルとURLをコピーしました