📽️

Tweenをもっと知る (Godot 3.x)

2022/02/11に公開

概説

Godotを使っていて得られた知見をGodot Engine / GDScript備忘録というスクラップに細々とまとめているのですが、Tweenに関するコメントの分量が増えてきたので、ちょっとした豆知識一覧として記事としてまとめ直しました。

なお、この記事で扱っているのはGodot 3.x時点でのTweenです。Godot 4.0でTweenを試してみるでも記事にしましたが、Godot 4.0からはTween周りが大幅に刷新され、本記事の内容は比較的すぐに陳腐化するかとは思います。もし、それまでの間、参考になるようでしたら幸いです。


Tweenひとつで大体OK

ひとつのTweenで複数のノード、そして変数を同時に扱うことができます。ですので、例えば色、位置、サイズをそれぞれ変更したい場合でも、個別にTweenを用意する必要はありません。

tween_completedでシグナルの切り分け

複数の補間を同時に実行する際に、補間の完了はどうやって検知するのが良いのでしょうか。tween_completedシグナルでは、どの補間が完了したのかが分からなくなりそうですね。

そういう場合は、tween_completedシグナルの引数であるNodeNodePathを条件分岐に使うことでシグナルを切り分けることが可能です。

tween_completedでシグナルを切り分ける
func _on_tween_completed(object: Object, key: NodePath):
    if object == self and key == NodePath(":rect_position"):
        # self の rect_position の補間が終わった後に実行したい処理をここに書く

    if object == _sprite and key == NodePath(":modulate"):
        # _sprite に代入されているノードの、
	# modulate の補間が終わった後に実行したい処理をここに書く

TransitionTypeのチートシート

redditにTransitionTypeごとのアニメーションの違いを図解してアップしている方がいるので、Tweenノードの正確な動きが知りたい場合は、そちらを参考にしてみてください[1][2]
https://www.reddit.com/r/godot/comments/frqzup/godot_tweening_cheat_sheet/

トゥイーンアニメーションをインタラクティブに確認できるサイトもあります。ただし、こちらはJS/CSSで実装されていて、GodotのTweenとは無関係です。GodotのTransitionTypeそのものを表しているわけではありませんので、なんとなくのイメージを掴む程度のものと理解して使うのが良いでしょう。


補間完了後に、コールバックでメソッド呼び出し

Tweenの補間完了後にメソッドを呼び出すのに、シグナル以外の方法を使いたいこともあると思います[3]。そういう場合には、interpolate_callback()を使うと良いです。

interpolate_callback()では、任意の秒数後に、指定したメソッドを実行することができます。

interpolate_callback()の使用例
func _run_tween():
    _tween.interpolate_property(self, "size", self.size, Vector2.ZERO, 0.6, Tween.TRANS_ELASTIC, Tween.EASE_IN_OUT)
    _tween.interpolate_callback(self, 0.6, "_on_tween_completed")
    _tween.start()

func _on_tween_completed():
    print("Tween Completed!")
    # _tween.start()の0.6秒後に「Tween Completed!」と出力されます

コールバックを実行するまでの秒数をハードコーディングしたくない場合、_tween.get_runtime()を使うのが良いです。この関数では、指定したTweenの補間完了までの秒数を取得できます。ただし、複数の処理が同時に走っている場合には、一番長い処理の秒数が返ってくるため、注意が必要です。

get_runtime()の使用例
func _run_tween():
    _tween.interpolate_property(self, "size", self.size, Vector2.ZERO, 0.6, Tween.TRANS_ELASTIC, Tween.EASE_IN_OUT)
    _tween.interpolate_property(self, "scale", self.scale, Vector2.ONE, 2.0, Tween.TRANS_CIRC, Tween.EASE_OUT)
    _tween.interpolate_callback(self, _tween.get_runtime(), "_on_tween_completed")
    _tween.start()

func _on_tween_completed():
    print("Tween Completed!")
    # 「Tween Completed!」と出力されるのは、_tween.start()の2秒後になります

interpolate_method()のちょっとだけ微妙なところ

interpolate_method()関数では、第2引数で指定されたメソッドに、Tweenで補間された値を渡すことができます。補間される値は第3, 4引数で指定します。

文章だけだと伝わりづらいと思うので、interpolate_method()の引数の詳細を以下に記載します。

interpolate_method()の引数の解説
interpolate_method (
    Object object, # 値を渡すメソッドが所属するオブジェクト
    String method, # 値を渡すメソッド
    Variant initial_val, # 補間する値の初期値
    Variant final_val, # 補間する値の終了値
    float duration, # 補間にかかる時間
    TransitionType trans_type=0, # トランジションの種類
    EaseType ease_type=2, # イージングの種類
    float delay=0 # 補間開始までの遅延時間
    )

Godot 3.4時点では、interpolate_method()の第3, 4引数に渡せる値は1つずつです。配列などで複数の値を渡すこともできないため、例えば複数の引数が必要なメソッドを補間させることはできません。

🚫 例えばこういう書き方はできません
_tween.interpolate_method(_graph_node, "set_slot_color_left"
, [0, Color.gray], [0, Color.red], 0.3, Tween.TRANS_QUINT, Tween.EASE_OUT)
# この例では、GraphNodeのset_slot_color_leftメソッド第2引数の補間を意図していますが、
# arrayで値を渡すようなことはできません

ちょっと不便ですね。ただ、これはTweenの仕様がガラッと変わった4.0の時点で改善されているそうです[4][5]

脚注
  1. 画像の二次利用について言及がないので、この記事では直接画像は貼らず、リンクするだけに留めておきます。 ↩︎

  2. ちなみにgithubでソースコードも公開されています。実際にGodot上で動作確認をしたい場合には、そちらもチェックしてみてください。 ↩︎

  3. Tweenを使う箇所が1箇所しかなく、補間完了までの秒数が分かりきっている場合など。個人的には、多少冗長になってもシグナルを使いますが…。 ↩︎

  4. こちらのissueでは「解決された」とされていますが、まだ自分では確認していません。https://github.com/godotengine/godot/issues/27425 ↩︎

  5. https://github.com/godotengine/godot/pull/41794 ↩︎

Discussion