animation-system について
Godot 4.3 以降の開発者向けに、AnimationPlayer、AnimationTree、スプライトアニメーション、3D のスケルトンアニメーションを解説するスキルです。GDScript と C# の例を掲載しています。
主な機能
- 01AnimationPlayer の再生と制御
- 02AnimationTree のステートマシンとブレンド
- 03スプライトフレームアニメーション
- 04アニメーションシグナルとメソッド呼び出しトラック
- 053D スケルトンモディファイアと IK
- 06アニメーションマーカーとリターゲティング
活用シーン
- 01キャラクターの歩行・攻撃アニメーション設定
- 02アニメーション状態間のスムーズな遷移
- 03アニメーションのフレームで当たり判定や音を発生
- 043D キャラクターのスケルトン IK 設定
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ jame581/ godotprompter --skill animation-systemインストール後、Claude Code で/animation-systemを入力して読み込まれたか確認します。
同梱ファイル
SKILL.md と一緒にインストールされる参考資料やスクリプト。
references/animation-markers.mdblend-spaces.mdbone-constraints.mdcommon-pitfalls.mdcommon-recipes.mdik-recipes.mdik-solver-comparison.mdretargeting.mdskeleton-modifiers.mdsprite-animation.mdstate-machine-examples.md詳細
翻訳後に原文が更新されています。最新の内容は原文をご確認ください。
Godot 4.3+ のアニメーションシステム
すべての例は、非推奨 API を使用せず Godot 4.3+ を対象としています。まず GDScript を示し、次に C# を示します。
関連スキル: ゲームプレイの状態管理には state-machine、アニメーションを駆動する移動には player-controller、再利用可能なアニメーションコンポーネントには component-system、TileMap、視差スクロール、2D ライト、CanvasLayer の構成には 2d-essentials、AnimationTree と 3D アニメーションのブレンドには 3d-essentials、シェーダーを使ったヒットフラッシュやディゾルブ効果には shader-basics、キーフレームアニメーションと並行してコードで動きを制御するには tween-animation を参照してください。
1. 基本概念
AnimationPlayer と AnimationTree
| ノード | 用途 | 複雑さ | 備考 |
|---|---|---|---|
AnimationPlayer | シンプルな再生、単発エフェクト | 低 | 個々のクリップを直接再生/停止/キューに追加します |
AnimationTree | ブレンド、トランジション、レイヤーアニメーション | 中~高 | スムーズなトランジションを実現するステートマシンとブレンドツリー |
目安: まずは AnimationPlayer から始めましょう。アニメーション間のブレンド(歩行/走行のブレンド、方向に応じた移動、上半身/下半身のレイヤー化)が必要になったら、AnimationTree を追加します。
アニメーションのワークフロー
1. Create AnimationPlayer node → holds all animation clips
2. Add tracks in the Animation panel → keyframe properties, methods, audio
3. (Optional) Add AnimationTree → blend/transition logic
4. Trigger from code → play(), travel(), set parameters
2. AnimationPlayer の基本
シーン構成
Character (CharacterBody2D)
├── Sprite2D
└── AnimationPlayer
AnimationPlayer は、兄弟ノードまたは子ノードの あらゆるプロパティ をアニメーション化できます。スプライトのフレーム、modulate、位置、回転、スケール、表示状態、CollisionShape の無効状態、メソッド呼び出し(Call Method トラック)、オーディオ再生(Audio Playback トラック)などが対象です。
GDScript — 基本的な再生
extends CharacterBody2D
@onready var anim_player: AnimationPlayer = $AnimationPlayer
func _physics_process(delta: float) -> void:
var input_dir := Input.get_vector("ui_left", "ui_right", "ui_up", "ui_down")
if input_dir != Vector2.ZERO:
velocity = input_dir * 200.0
anim_player.play("walk")
else:
velocity = Vector2.ZERO
anim_player.play("idle")
move_and_slide()
C# — 基本的な再生
using Godot;
public partial class Character : CharacterBody2D
{
private AnimationPlayer _animPlayer;
public override void _Ready()
{
_animPlayer = GetNode<AnimationPlayer>("AnimationPlayer");
}
public override void _PhysicsProcess(double delta)
{
Vector2 inputDir = Input.GetVector("ui_left", "ui_right", "ui_up", "ui_down");
if (inputDir != Vector2.Zero)
{
Velocity = inputDir * 200.0f;
_animPlayer.Play("walk");
}
else
{
Velocity = Vector2.Zero;
_animPlayer.Play("idle");
}
MoveAndSlide();
}
}
再生中のアニメーションと同じ名前を指定して
play()を呼び出しても、何も起こりません(最初から再生し直すことはありません)。毎フレーム呼び出しても安全です。
再生の制御
anim_player.play("attack")
anim_player.play_backwards("attack")
anim_player.queue("idle") # play after current
anim_player.stop()
anim_player.pause()
anim_player.play() # resume from paused position
anim_player.speed_scale = 2.0
anim_player.seek(0.5)
_animPlayer.Play("attack");
_animPlayer.PlayBackwards("attack");
_animPlayer.Queue("idle");
_animPlayer.Stop();
_animPlayer.Pause();
_animPlayer.Play();
_animPlayer.SpeedScale = 2.0;
_animPlayer.Seek(0.5);
3. アニメーションシグナル
func _ready() -> void:
anim_player.animation_finished.connect(_on_animation_finished)
func _on_animation_finished(anim_name: StringName) -> void:
match anim_name:
"attack":
anim_player.play("idle")
"death":
queue_free()
public override void _Ready()
{
_animPlayer = GetNode<AnimationPlayer>("AnimationPlayer");
_animPlayer.AnimationFinished += OnAnimationFinished;
}
private void OnAnimationFinished(StringName animName)
{
if (animName == "attack")
_animPlayer.Play("idle");
else if (animName == "death")
QueueFree();
}
メソッド呼び出しトラック
Call Method トラックを追加すると、アニメーションの正確なフレームでゲームロジックを実行できます(5 フレーム目に飛び道具を生成する、命中フレームで効果音を再生する、振りかぶり中に当たり判定を有効にする、など)。Animation パネルで「トラックを追加」→「Call Method Track」→ 対象ノードを選択 → キーフレームを追加 → メソッド名と引数を設定します。
func spawn_projectile() -> void:
var bullet := preload("res://scenes/bullet.tscn").instantiate()
get_parent().add_child(bullet)
bullet.global_position = $Muzzle.global_position
func enable_hitbox() -> void:
$HitboxArea/CollisionShape2D.disabled = false
4. スプライトのフレームアニメーション
2D キャラクターのアニメーションには、AnimatedSprite2D(手軽で、フレームのみ)と AnimationPlayer + Sprite2D(プロパティ全般をアニメーション化)の 2 つの方法があります。シンプルなキャラクターには AnimatedSprite2D を、当たり判定、パーティクル、サウンドなどのプロパティも同期してアニメーション化する場合は AnimationPlayer を選びます。
完全な GDScript と C# の例(
Input.get_vectorとflip_hでAnimatedSprite2Dを駆動して歩く CharacterBody2D)については、references/sprite-animation.md を参照してください。
ピンポン再生(Godot 4.7+)
SpriteFrames には LoopMode 列挙型が追加されました。LOOP_NONE = 0、LOOP_LINEAR = 1、LOOP_PINGPONG = 2 があり、アニメーションごとに set_animation_loop_mode(anim, loop_mode) で設定し、get_animation_loop_mode(anim) で取得できます。以前の bool 型の set_animation_loop()/get_animation_loop() は非推奨です。ピンポン再生では、アニメーションが終端または始端に達するたびに再生方向が切り替わり、AnimatedSprite2D と AnimatedSprite3D の両方で使用できます。
var frames: SpriteFrames = $AnimatedSprite2D.sprite_frames
frames.set_animation_loop_mode(&"sway", SpriteFrames.LOOP_PINGPONG)
var frames = GetNode<AnimatedSprite2D>("AnimatedSprite2D").SpriteFrames;
frames.SetAnimationLoopMode("sway", SpriteFrames.LoopMode.Pingpong);
5. AnimationTree — 標準的なステートマシン
シーン構成
Character (CharacterBody2D)
├── Sprite2D
├── AnimationPlayer ← holds all clips
└── AnimationTree ← controls blending/transitions
(tree_root = AnimationNodeStateMachine or AnimationNodeBlendTree)
設定: AnimationPlayer の兄弟ノードとして AnimationTree を追加します。anim_player に AnimationPlayer を指定します。active = true に設定します。ルートとして、AnimationNodeStateMachine(トランジションのある個別の状態)または AnimationNodeBlendTree(連続的なブレンド)を選択します。
ステートマシンの再生
基本的なパターンは、anim_tree["parameters/playback"] から AnimationNodeStateMachinePlayback をキャッシュし、ゲームプレイコードから travel("state") を呼び出し(travel() は滑らかに遷移し、start() は即座に切り替わります)、get_current_node() でアクティブなステートを取得することです。
GDScript と C# による CharacterBody2D の完全な例については、references/state-machine-examples.md を参照してください。
ブレンドツリー — BlendSpace1D / BlendSpace2D
連続的なブレンド(速度パラメーターによる歩行↔走行、2D ベクトルによる 4 方向/8 方向の移動)に使用します。ルートを AnimationNodeBlendTree に設定し、BlendSpace1D または BlendSpace2D を追加して、アニメーションをコンパス上の位置に配置します(例:walk @ 0.0、run @ 1.0、idle_down @ (0,1)、idle_right @ (1,0))。毎フレーム、ブレンドを更新します。
# 1D — speed blend
var blend_amount := inverse_lerp(walk_speed, run_speed, velocity.length())
anim_tree["parameters/BlendSpace1D/blend_position"] = blend_amount
# 2D — direction blend
anim_tree["parameters/BlendSpace2D/blend_position"] = input_dir
_animTree.Set("parameters/BlendSpace1D/blend_position", blendAmount);
_animTree.Set("parameters/BlendSpace2D/blend_position", inputDir);
名前付きブレンドポイント(Godot 4.7+)
AnimationNodeBlendSpace1D/2D.add_blend_point() に省略可能な name: StringName = &"" パラメーターが追加され、ブレンドポイントの名前/インデックスを設定してエディターに表示できるようになりました。名前を明示的に渡すことを推奨します(空の名前は非推奨になる予定です)。find_blend_point_by_name() でポイントを検索できます。
blend_space.add_blend_point(walk_node, 0.0, -1, &"walk")
blend_space.add_blend_point(run_node, 1.0, -1, &"run")
var run_index := blend_space.find_blend_point_by_name(&"run")
blendSpace.AddBlendPoint(walkNode, 0.0f, -1, "walk");
blendSpace.AddBlendPoint(runNode, 1.0f, -1, "run");
int runIndex = blendSpace.FindBlendPointByName("run");
⚠️ Godot 4.7 での変更点:
AnimationNodeBlendSpace1D/2Dでは、bool 型のsyncプロパティ(現在は非推奨)に代わり、sync_modeのSyncMode列挙型を使用します。SYNC_MODE_NONE = 0(デフォルト — 非アクティブなアニメーションは停止します)、SYNC_MODE_INDEPENDENT = 1(従来のsync = trueの動作)、SYNC_MODE_CYCLIC_MUTABLE = 2(ブレンドの重みからサイクル長を動的に計算)、SYNC_MODE_CYCLIC_CONSTANT = 3(cyclic_length秒ごとに 1 サイクル — 0 より大きい値が必要)があります。4.6 で正しくブレンドされていた AnimationTree の遷移が正しく動作しなくなった場合は、各ブレンドスペースのsync_modeを設定してください。4.7 の移行ガイド を参照してください。
6. スケルトンモディファイア(3D、4.4+)
LookAtModifier3D(Godot 4.4+)
ワールド空間のターゲットを見るように、ボーンをプロシージャルに回転させます。追加のアニメーションクリップを使わずに、頭部のトラッキングやアイコンタクトを実現するのに適しています。
角度制限と影響度のブレンドを含む GDScript および C# の完全な例については、references/skeleton-modifiers.md を参照してください。
⚠️ Godot 4.7 での変更点:
LookAtModifier3D.relativeのデフォルト値がfalseになりました。回転は現在のポーズではなく、レストポーズを基準に適用されます。デフォルトがtrueだったのは 4.6.0 のみです。この変更は 4.6.1 にもバックポートされたため、4.6.1 以降から移行するプロジェクトでは違いはありません。4.6.0 の動作に戻すには、relative = trueを設定してください。4.7 の移行ガイド を参照してください。
BoneConstraint3D(Godot 4.5+)
AimModifier3D、CopyTransformModifier3D、ConvertTransformModifier3D はワールド空間ではなく、ボーン相対で動作します。照準/ソースのターゲット自体が同じスケルトン上のボーンである場合(ミラーリング、セカンダリーリグのバインド、ボーン間の照準)に使用してください。
AimModifier3D と CopyTransformModifier3D のモディファイア一覧、シーン構成、GDScript および C# の例を含む詳細な解説については、references/bone-constraints.md を参照してください。
SpringBoneSimulator3D(Godot 4.4+)
ボーンにバネの物理演算を適用します。髪、マント、尻尾、アンテナをプロシージャルに揺らせます。Skeleton3D の子として追加し、インスペクターでスプリングチェーン(ルートボーン、エンドボーン、半径、剛性、ドラッグ、重力)を設定します。
プロパティの一覧と、用途別(髪、アンテナ、マント)の推奨初期値については、references/skeleton-modifiers.md を参照してください。
アニメーションマーカー(Godot 4.4+)
マーカーは、アニメーションクリップ内の名前付きポイントや領域を定義します。クリップを分割せずに、サブリージョンのループ、セクション単位の再生、音声と同期したイベントに使用できます。アニメーションのタイムラインを右クリックし、マーカーを挿入... を選択して名前(例:hit_frame、loop_start)を付けます。anim_player.play_section_with_markers(&"attack", &"loop_start", &"loop_end") で領域を再生するか、animation.get_marker_time(&"hit_frame") と anim_player.current_animation_position を比較します。
アニメーションのリターゲティング(Godot 4.3+)
Godot 4.3では、.glb/.gltf のインポート時に SkeletonProfile(例:SkeletonProfileHumanoid)を介して、あるスケルトンから別のスケルトンへアニメーションをリターゲティングできます。アニメーションは汎用プロファイルのボーン名を対象とするため、名前が一致するスケルトンであれば再生できます。
インポートドックの設定手順については、references/retargeting.md を参照してください。
7. IKModifier3D — ソルバーの比較(Godot 4.6+)
Godot 4.6では、スケルトンIKソルバーの基底クラス IKModifier3D が追加されました。すぐに使えるソルバーは5種類あります:TwoBoneIK3D、CCDIK3D、FABRIK3D、JacobianIK3D、SplineIK3D です。これらは Skeleton3D の子である SkeletonModifier3D で、ほかのモディファイア(例:LookAtModifier3D)と併用できます。
チェーンに応じて選択します。ボーンがちょうど2本の四肢には(ポールノードが必要な)TwoBoneIK3D、関節制限のないシンプルなチェーンには FABRIK3D、関節に制限がある場合は CCDIK3D、Path3D に沿わせるには SplineIK3D、追従は遅めでも滑らかで有機的な動きには JacobianIK3D を選びます。
ソルバーの比較表と選択の指針については、references/ik-solver-comparison.md を参照してください。
GDScriptおよびC#のレシピ一式(影響度のブレンドを使った腕のリーチ(CCDIK3D)、不整地での足の配置(FABRIK3D + レイキャスト)、基本的なFABRIK腕IKの設定)については、references/ik-recipes.md を参照してください。
8. よく使うレシピ
ゲームプレイを意識したアニメーションのレシピを2つ紹介します。ヒット時のフラッシュ用モジュレートトゥイーンと、AnimationPlayerのCall Methodトラックを使ったバッファリング付き攻撃コンボです。
GDScriptおよびC#のコード一式(ヒットフラッシュ、コンボ受付時間のバッファリング付き攻撃コンボ)については、references/common-recipes.md を参照してください。
9. よくある落とし穴
アニメーションがブレンドせずに急に切り替わる、AnimationTreeが無効になっている、travel() で遷移しない、トラックのノードパスが間違っている、Call Methodトラックが無音になる、ブレンドパラメーターが機能しない、毎フレームの play() でリセットされる、といった問題を症状 → 原因 → 修正の形式でまとめた表です。
表全体については、references/common-pitfalls.md を参照してください。
10. 実装チェックリスト
- AnimationPlayer がアニメーション対象ノードの直接の子になっていること(さらに下の階層にネストされていないこと)
- すべてのアニメーショントラックのノードパスが有効であること(シーンの構成変更後に参照切れがないこと)
- AnimationTree の
activeがtrueに設定され、anim_playerが正しい AnimationPlayer を指していること - ステートマシンのトランジションに適切なフェード時間が設定されていること(レスポンスの良いゲームプレイには 0.1~0.2 秒)
- ループするアニメーション(idle、walk、run)のループモードが Animation パネルで Loop に設定されていること
- 1 回限りのアニメーション(attack、jump、death)のループモードが None に設定されていること
- ゲームプレイイベント(ヒットボックスの有効化/無効化、投射物の生成、SFX の再生)に Call Method トラックを使用していること
- ブレンドパラメーターを状態変更時だけでなく、毎フレームゲームプレイコードから設定していること
- 後続処理が必要な 1 回限りのアニメーションで
animation_finishedシグナルを接続していること - 頭部/目のトラッキングに手動のボーン回転ではなく
LookAtModifier3Dを使用していること(Godot 4.4 以降) - 髪、マント、尻尾にカスタム物理スクリプトではなく
SpringBoneSimulator3Dを使用していること(Godot 4.4 以降) - 共有アニメーションライブラリで
SkeletonProfileHumanoidによるリターゲティングを使用していること(Godot 4.3 以降) - ボーン間の照準/コピー制約に、手動のボーントランスフォームコードではなく
AimModifier3D/CopyTransformModifier3Dを使用していること(Godot 4.5 以降) - 腕/脚の IK にカスタム IK スクリプトではなく IKModifier3D のサブクラスを使用していること(2 ボーンの四肢にはポールノードを設定した
TwoBoneIK3D、より長いチェーンにはFABRIK3DまたはCCDIK3D)(Godot 4.6 以降)