tween-animation について
Godot 4.3+の開発者向けTweenアニメーションスキルです。GDScriptとC#の例で、プロパティアニメーション、順序制御、イージング、ライフサイクルを扱います。
主な機能
- 01プロパティ、メソッド、コールバックのアニメーション
- 02逐次・並列のシーケンス制御
- 03トランジションとイージングの設定
- 04ループ、シグナル、ライフサイクル管理
- 05定番レシピとトラブルシューティング
活用シーン
- 01UIのフェードやパネルスライドの作成
- 02移動、回転、スケールの連続制御
- 03ボタンのバウンスや画面シェイクの作成
- 04Tweenの競合や一時停止動作の調査
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ jame581/ godotprompter --skill tween-animationインストール後、Claude Code で/tween-animationを入力して読み込まれたか確認します。
同梱ファイル
SKILL.md と一緒にインストールされる参考資料やスクリプト。
references/common-recipes.mdlifecycle.mdlooping-and-signals.mdproperty-tweener-modifiers.md詳細
Godot 4.3 以降の Tween
すべての例は、非推奨 API を使用せずに Godot 4.3 以降を対象としています。まず GDScript を示し、その後に C# を示します。
関連スキル: キーフレームベースの AnimationPlayer/AnimationTree については animation-system、UI のトランジションについては godot-ui、シェーダーパラメーターの Tween については shader-basics、カメラの揺れやトランジションについては camera-system、イージングカーブや補間の計算については math-essentials、コード駆動の VFX のタイミングや順序制御については particles-vfx を参照してください。
1. 基本概念
Tween と AnimationPlayer の比較
| 機能 | Tween(コード駆動) | AnimationPlayer(データ駆動) |
|---|---|---|
| セットアップ | コードのみ — エディターは不要 | キーフレームを使うアニメーションパネル |
| 最適な用途 | プロシージャルな動き、UI のトランジション、VFX | 複雑なマルチトラック、アーティストが作成するクリップ |
| 再利用性 | 使用するたびに再作成 — 軽量 | リソースとして保存し、シーン間で再利用可能 |
| ブレンド | いいえ — 同時に扱えるのはプロパティごとに Tween 1 つ | はい — AnimationTree でブレンド可能 |
| メソッド呼び出し | 任意の時点で tween_callback() を実行 | キーフレームの時点で Call Method トラックを実行 |
目安: フェードイン、バウンス、スライドなど、一度限りのプロシージャルアニメーションには Tween を使用します。歩行サイクルや攻撃シーケンスなど、繰り返し再生する、アーティストが調整したアニメーションには AnimationPlayer を使用します。
Tween の作成
Tween は任意の Node から作成でき、自動的にそのノードにバインドされます。ノードが解放されると、Tween も自動的に停止します。
# Creates a tween bound to this node
var tween := create_tween()
tween.tween_property(self, "position", Vector2(400, 300), 1.0)
var tween = CreateTween();
tween.TweenProperty(this, "position", new Vector2(400, 300), 1.0f);
重要:
create_tween()を呼び出すたびに、新しい Tween が作成されます。同じプロパティに対する以前の Tween が自動的に停止されることはありません。競合するため、同じプロパティに新しい Tween を作成する前に、競合を避けたい場合は古い Tween を停止してください。
2. Tweener の種類
tween_property() — 任意のプロパティをアニメーションさせる
var tween := create_tween()
# Animate position over 0.5 seconds
tween.tween_property($Sprite2D, "position", Vector2(200, 100), 0.5)
# Animate modulate alpha (fade out)
tween.tween_property($Sprite2D, "modulate:a", 0.0, 0.3)
var tween = CreateTween();
tween.TweenProperty(GetNode("Sprite2D"), "position", new Vector2(200, 100), 0.5);
tween.TweenProperty(GetNode("Sprite2D"), "modulate:a", 0.0f, 0.3);
サブプロパティへのアクセス: : を使うと個別のコンポーネントを指定できます — "position:x"、"modulate:a"、"scale:y"。
tween_callback() — シーケンスの途中でメソッドを呼び出す
var tween := create_tween()
tween.tween_property(self, "position", Vector2.ZERO, 0.5)
tween.tween_callback(func(): print("Arrived!"))
tween.tween_callback(queue_free)
var tween = CreateTween();
tween.TweenProperty(this, "position", Vector2.Zero, 0.5f);
tween.TweenCallback(Callable.From(() => GD.Print("Arrived!")));
tween.TweenCallback(Callable.From(QueueFree));
tween_interval() — ステップ間で待機/遅延する
var tween := create_tween()
tween.tween_property(self, "modulate:a", 0.0, 0.3) # fade out
tween.tween_interval(1.0) # wait 1 second
tween.tween_property(self, "modulate:a", 1.0, 0.3) # fade back in
var tween = CreateTween();
tween.TweenProperty(this, "modulate:a", 0.0f, 0.3);
tween.TweenInterval(1.0f);
tween.TweenProperty(this, "modulate:a", 1.0f, 0.3);
tween_method() — 補間値を使ってカスタムメソッドをアニメーションさせる
# Animate a method that receives interpolated float values
func _ready() -> void:
var tween := create_tween()
tween.tween_method(_set_health_bar, 100.0, 0.0, 2.0)
func _set_health_bar(value: float) -> void:
$HealthBar.value = value
$HealthLabel.text = "%d%%" % int(value)
public override void _Ready()
{
var tween = CreateTween();
tween.TweenMethod(Callable.From<float>(SetHealthBar), 100.0f, 0.0f, 2.0f);
}
private void SetHealthBar(float value)
{
GetNode<ProgressBar>("HealthBar").Value = value;
GetNode<Label>("HealthLabel").Text = $"{(int)value}%";
}
3. シーケンス — 連続実行と並列実行
逐次実行(デフォルト)
デフォルトでは、Tweener は逐次実行されます — それぞれが前の処理の終了を待ちます。
var tween := create_tween()
tween.tween_property(self, "position:x", 300.0, 0.5) # Step 1
tween.tween_property(self, "position:y", 200.0, 0.5) # Step 2 (after Step 1)
tween.tween_property(self, "rotation", PI, 0.3) # Step 3 (after Step 2)
並列実行 — Tweener を同時に実行する
オプション 1:set_parallel(true) — すべての Tweener を同時に実行する
var tween := create_tween().set_parallel(true)
tween.tween_property(self, "position", Vector2(300, 200), 0.5)
tween.tween_property(self, "rotation", PI, 0.5)
tween.tween_property(self, "modulate:a", 0.5, 0.5)
var tween = CreateTween().SetParallel(true);
tween.TweenProperty(this, "position", new Vector2(300, 200), 0.5f);
tween.TweenProperty(this, "rotation", Mathf.Pi, 0.5f);
tween.TweenProperty(this, "modulate:a", 0.5f, 0.5f);
オプション 2:chain() — Tween の途中で逐次実行に戻す
var tween := create_tween().set_parallel(true)
# These two run at the same time
tween.tween_property(self, "position", Vector2(300, 200), 0.5)
tween.tween_property(self, "scale", Vector2(2, 2), 0.5)
# Switch back to sequential for the next step
tween.chain().tween_property(self, "modulate:a", 0.0, 0.3)
tween.tween_callback(queue_free)
var tween = CreateTween().SetParallel(true);
tween.TweenProperty(this, "position", new Vector2(300, 200), 0.5f);
tween.TweenProperty(this, "scale", new Vector2(2, 2), 0.5f);
tween.Chain().TweenProperty(this, "modulate:a", 0.0f, 0.3f);
tween.TweenCallback(Callable.From(QueueFree));
オプション 3:parallel() — 次の Tweener を直前の Tweener と並列実行する
var tween := create_tween()
tween.tween_property(self, "position", Vector2(300, 200), 0.5)
# This runs at the same time as position, not after
tween.parallel().tween_property(self, "rotation", PI, 0.5)
# This runs after both finish (back to sequential)
tween.tween_callback(func(): print("done"))
4. イージングとトランジション
イージングの設定
var tween := create_tween()
# Set defaults for the entire tween
tween.set_trans(Tween.TRANS_CUBIC).set_ease(Tween.EASE_OUT)
tween.tween_property(self, "position", Vector2(400, 300), 0.6)
var tween = CreateTween();
tween.SetTrans(Tween.TransitionType.Cubic).SetEase(Tween.EaseType.Out);
tween.TweenProperty(this, "position", new Vector2(400, 300), 0.6f);
Tweener ごとの上書き
var tween := create_tween()
# This tweener uses bounce, overriding the tween default
tween.tween_property(self, "position:y", 0.0, 0.5) \
.set_trans(Tween.TRANS_BOUNCE).set_ease(Tween.EASE_OUT)
var tween = CreateTween();
tween.TweenProperty(this, "position:y", 0.0f, 0.5f)
.SetTrans(Tween.TransitionType.Bounce)
.SetEase(Tween.EaseType.Out);
トランジションの種類
| トランジション | 特徴 | 一般的な用途 |
|---|---|---|
TRANS_LINEAR | 速度が一定 | プログレスバー、タイマー |
TRANS_SINE | 緩やかな加速 | さりげない UI アニメーション |
TRANS_QUAD | 適度なカーブ | 一般的な動き |
TRANS_CUBIC | 滑らかなカーブ | ほとんどの UI トランジション |
TRANS_QUART | 強いカーブ | 印象的な登場演出 |
TRANS_QUINT | 非常に強いカーブ | 強調効果 |
TRANS_EXPO | 指数関数的 — 急な開始/停止 | 位置へのスナップ |
TRANS_CIRC | 円形 — 滑らかな減速 | 自然な動き |
TRANS_BACK | 目標をわずかに行き過ぎます | 弾む UI ボタン |
TRANS_ELASTIC | バネのような振動 | 遊び心のある/漫画風の効果 |
TRANS_BOUNCE | 終端で弾みます | 物体の落下、着地 |
イージングの種類
| イージング | 動作 |
|---|---|
EASE_IN | ゆっくり始まり、速く終わります |
EASE_OUT | 速く始まり、ゆっくり終わります(最も自然です) |
EASE_IN_OUT | 始まりと終わりの両方がゆっくりです |
EASE_OUT_IN | 始まりと終わりの両方が速いです(あまり使われません) |
最も一般的な組み合わせ: 自然な UI トランジションには
TRANS_CUBIC+EASE_OUTを使います。遊び心のある弾むような登場演出にはTRANS_BACK+EASE_OUTを使います。
5. PropertyTweener モディファイア
各 tween_property() 呼び出しは PropertyTweener を返します。次のモディファイアをチェーンできます:カスタムの開始値を指定する .from(value)、現在の値を取得する .from_current()、値を置き換えずに加算する .as_relative()、この tweener の開始を遅らせる .set_delay(seconds)。
各モディファイアのコード例については、references/property-tweener-modifiers.md を参照してください。
6. ループとシグナル
tween.set_loops(N) は N 回繰り返します(0 = 無限)。シグナル:finished(tween 全体の完了)、step_finished(idx)(1 ステップの完了)、loop_finished(loop_count)(1 サイクル全体の完了。最後のループ後には発生せず、そのときは finished が発生します)。
ループ回数の仕様とシグナルの接続については、references/looping-and-signals.md を参照してください。
7. Tween のライフサイクル
Tween はホストの SceneTree に所有されます。Tween の多重実行を避けるには、新しいものを開始する前に実行中の Tween を tween.kill() で終了させます。実行時の制御には set_pause_mode、set_speed_scale、および(Godot 4.4 以降)set_ignore_time_scale を使います。
終了/置き換えのパターン、一時停止モード、速度スケール、時間スケールの無視については、references/lifecycle.md を参照してください。
has_tweeners()(Godot 4.7 以降)
Tween.has_tweeners()(const)は、Tween が有効で、1 つ以上の Tweener が追加されている場合に true を返します。Tweener が動的に追加され、Tween が空になる可能性がある場合に便利です。空の Tween は、開始前に終了させることでエラーを防げます。
var tween := create_tween()
_add_intro_steps(tween) # may append zero tweeners
if not tween.has_tweeners():
tween.kill()
var tween = CreateTween();
AddIntroSteps(tween); // may append zero tweeners
if (!tween.HasTweeners())
tween.Kill();
8. よく使われるレシピ
多くのプロジェクトで必要となるパターン:フェードイン/アウト、UI パネルのスライドイン/アウト、ボタンを押したときのバウンス、ダメージ数値のポップアップ、脈打つ/呼吸するような効果、画面の揺れ、シェーダーパラメーターのアニメーション。
各レシピですぐに使えるコードについては、references/common-recipes.md を参照してください。
9. よくある落とし穴
| 症状 | 原因 | 対処法 |
|---|---|---|
| Tween が跳ねたり、ぎくしゃくしたりする | 同じプロパティで複数の Tween が競合している | 新しい Tween を作成する前に、古い Tween を停止する |
| Tween が何もしない | Tween の完了前にノードが解放された | is_valid() を確認するか、await の代わりに tween_callback を使用する |
| 一時停止中に Tween が動作または停止する | デフォルトの TWEEN_PAUSE_BOUND は、バインドされたノードの process_mode に従う | 常に一時停止する場合は TWEEN_PAUSE_STOP、動作を続ける場合は TWEEN_PAUSE_PROCESS を使用する |
from() の値が無視される | from() の値は、そのトゥイーナーの開始時にのみ適用される | それより前に表示する必要がある場合は、まずプロパティに開始値を設定する |
| Tween が滑らかにループしない | シームレスなループに必要な終了値と開始値が一致していない | 回転には as_relative() を使用するか、開始値と終了値を一致させる |
| 相対 Tween がループごとにずれていく | as_relative() はループごとに値が累積する | ループには絶対値を、単発の移動には相対値を使用する |
| コールバックが適切でないタイミングで呼び出される | コールバックが並列セクションに追加された | コールバックの前に chain() を使用して逐次処理に戻す |
| Tween のプロパティパスが見つからない | パスの誤記、または形式が正しくない | "property:component" を使用する。例:"position:x"、"modulate:a" |
| Tween が予想より速く/遅く動作する | Engine.time_scale が Tween に影響する | スローモーション中の UI Tween には set_ignore_time_scale()(4.4+)を使用する |
10. 実装チェックリスト
- 同じプロパティに対して新しい Tween を作成する前に、古い Tween を停止している
- 後で停止する必要がある場合は、Tween の参照を変数に保存している
- イージングを設定している(自然な動きには
TRANS_CUBIC+EASE_OUTを使用し、デフォルトのTRANS_LINEARは使用しない) - 複数のプロパティを同時にアニメーションさせる場合は、
set_parallel(true)を使用している - 並列セクションの後に逐次処理へ戻すには、
chain()を使用している - 開始値が重要な場合は、
from()またはfrom_current()を使用している(終了値だけではない) - 絶対値の目標を計算する代わりに、増分移動には
as_relative()を使用している - ループする Tween には、手動で再作成するのではなく
set_loops()を使用している - 一時停止中も動作させる必要がある Tween には、
set_pause_mode(TWEEN_PAUSE_PROCESS)を使用している - 一度限りの処理シーケンス(ダメージ数値、パーティクル)の最後に、
tween_callback(queue_free)を使用している