🍩

Godot4.2.1でのTweenの使い方について

2024/05/27に公開


Godot4.2.1を使用して実験しています
Unityのアセットの中で、屈指の人気を誇るものの一つにDoTweenがあります。
GameObjectを簡単にアニメーションさせる事ができる強力なアセットで、もちろん僕も多用しています。
Godotでも同じような事ができないか確認してみると、Tweenと、そのままの名前でありました。

Godotはバージョン3.※版から4.※版にアップされた際、かなり劇的な変更が加えられたようで、このTweenも使い方が大きく変わった様です。
実際、ネットの記事を調べてみると、3.※版対象にしていたり、4.※版対応と書かれていても、記事の動きと実際の動きが微妙に異なっていたりと、まだ完全には対応しきれていない情報が多い様でした。

今回、ColorChangePanicを移植する際、色々と実験してみましたので、Tweenについてまとめておこうと思います。

事前準備

Tweenは以前はノードの一つだった様ですが、4.2.1版では、スクリプトで変数にインスタンス化して使用します。

var _tween = get_tree().create_tween()

Tweenをインスタンス化する変数を宣言します。
_ready関数より前に宣言しようとすると、エラーになってしまいますので注意が必要です。
Tweenをその関数内でしか使用しないのであれば、この宣言はその関数内で良いと思います。

基本の文法

_tween.tween_property(対象のノード ,  変化させたいプロパティ , 変化後の値 ,  変化に必要な時間(秒))
_tween.play() #← このメソッドでTweenが開始される。

_tween.tween_property($ColorRect, "scale", Vector2(2,2), 2.0)
_tween.play() 

ColorRectノードのscaleプロパティを、2秒かけて、scale.x:2、scale.y:2に変化させます。
tween_propertyで変化を指示すると、一行ごとに変化完了させます。

次の様に二行で書くと、

_tween.tween_property($ColorRect, "scale", Vector2(2,2), 2.0)
_tween.tween_property($ColorRect, "scale", Vector2(1,1), 2.0)
_tween.play() 


この様に、最初の行の変化が完了してから、次の変化を行います。

同時に複数の変化を起こしたい場合は、最初の変化の指示した行の次にparallel()をつけます。
parallel()の説明をみると、「次のTweenerを前のTweenerと並行して実行します。」とありますので、最初の行は普通に指定して、次の行にこのparallel()を指定する様です。

同じようにparallel()の行を繰り返せば、同時に変化する動作を増やすことができます。

_tween.tween_property($ColorRect, "scale", Vector2(2,2), 2.0)
_tween.parallel().tween_property($ColorRect,"position", $ColorRect.position+Vector2(100,0), 2.0)
_tween.parallel().tween_property($ColorRect,"self_modulate", Color(1,1,1,0), 2.0)
_tween.play() 


大きくなりながら、横に移動しつつ、透明になっていく、という3つの変化を同時に実行できます。

シグナル

以前はノードだったからなのか、Tweenにはシグナルがあります。
このシグナルを利用することで、Tweenの終わりに関数を実行させることもできます。

func _Move_Tween():
	var _tween = get_tree().create_tween()
	_tween.finished.connect(_Tween_end) # ← シグナルを接続する。

	_tween.tween_property($ColorRect,"position", $ColorRect.position+Vector2(100,0), 2.0)
	_tween.tween_interval(2)#ここで2秒まつ
	_tween.tween_property($ColorRect,"position", $ColorRect.position, 2.0)
	
	_tween.play()
	pass

func _Tween_end():
	print("Tweenは完了しました。")

https://www.youtube.com/watch?v=6ozxYTYX630&t=1s

Tween途中の座標の考え方

僕は間違えて混乱したんですが、移動を指示する場合の基準の座標は、移動を指示する行の時点の座標ではなく、play()が実行された時点の座標になる様です。
先程のコードの例で言いますと

_tween.tween_property($ColorRect,"position", $ColorRect.position+Vector2(100,0), 2.0)
_tween.tween_interval(2)
_tween.tween_property($ColorRect,"position", $ColorRect.position, 2.0)

最初の行が、初期位置から右に100ピクセル移動する。というのは分かりやすいと思います。

ですが、3行目は一見すると、$ColorRect,"position"が2秒かけて、$ColorRect.positionに移動する。
つまり、移動しない指示の様に見えます。
ところが実際には、先ほどご覧いただいた様に元の位置に戻る動きになります。

つまり、3行目で変化後の値として設定されている「position」の座標は、この移動指示を指定した行での、ノードの実際のposition(右に100ピクセル移動した座標)ではなく、「play()が実行された時点の座標」になる様です。


Discussion