/animation-system
Use when implementing animations — AnimationPlayer, AnimationTree, blend trees, state machines, sprite animation, and code-driven animation
$ npx -y skills add jame581/GodotPrompter --skill animation-system --agent claude-codeHow it fires
How this skill gets triggered: by you, by Claude, or both.
- Fires itselfAuto-invocation. Claude auto-loads it when your prompt matches the work.Auto-invocation is when the right skill fires by itself at the right moment, driven by a FLOW.md router and a hook, instead of you invoking it by name. It is the difference between a skill being installed and a skill actually getting used.Read the full definition →
- You can call itInvoke it directly when you want it.
- Slash command
/animation-system
Context preview
The summary Claude sees to decide when to auto-load this skill.
Use when implementing animations — AnimationPlayer, AnimationTree, blend trees, state machines, sprite animation, and code-driven animation
SKILL.md
animation-system.SKILL.mdname: animation-system
description: Use when implementing animations — AnimationPlayer, AnimationTree, blend trees, state machines, sprite animation, and code-driven animation
Animation System in Godot 4.3+
All examples target Godot 4.3+ with no deprecated APIs. GDScript is shown first, then C#.
> **Related skills:** **state-machine** for gameplay state management, **player-controller** for movement that drives animation, **component-system** for reusable animation components, **2d-essentials** for TileMaps, parallax scrolling, 2D lights, and canvas layer organization, **3d-essentials** for AnimationTree and 3D animation blending, **shader-basics** for shader-driven hit flash and dissolve effects, **tween-animation** for code-driven motion alongside keyframe animation.
---
1. Core Concepts
AnimationPlayer vs AnimationTree
| Node | Use For | Complexity | Notes | |-------------------|------------------------------------------|------------|----------------------------------------------------| | `AnimationPlayer` | Simple playback, one-shot effects | Low | Play/stop/queue individual clips directly | | `AnimationTree` | Blending, transitions, layered animation | Medium-High| State machines and blend trees for smooth transitions |
**Rule of thumb:** Start with AnimationPlayer. Add AnimationTree when you need blending between animations (walk/run blend, directional movement, layered upper/lower body).
Animation Workflow
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 Basics
Scene Structure
Character (CharacterBody2D)
├── Sprite2D
└── AnimationPlayer
AnimationPlayer can animate **any property** on any sibling or child node: sprite frames, modulate, position, rotation, scale, visibility, collision shape disabled state, method calls (Call Method track), audio playback (Audio Playback track).
GDScript — Basic Playback
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# — Basic Playback
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();
}
}> Calling `play()` with the same animation name while it's already playing does nothing (no restart). This is safe to call every frame.
Playback Control
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. Animation Signals
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();
}Method Call Tracks
Add a **Call Method** track to trigger game logic at exact animation frames (spawn projectile at frame 5, play SFX at impact frame, enable hitbox during swing). In the Animation panel: Add Track → Call Method Track → select target node → add keyframes → set method name and arguments.
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. Sprite Frame Animation
Two approaches for 2D character animation: `AnimatedSprite2D` (quick, frames-only) and `AnimationPlayer + Sprite2D` (full property animation). Pick AnimatedSprite2D for simple characters; AnimationPlayer when you also animate hitboxes, particles, sounds, or other properties in sync.
> See [references/sprite-animation.md](references/sprite-animation.md) for the full GDScript and C# example (a CharacterBody2D walking with `AnimatedSprite2D` driven by `Input.get_vector` and `flip_h`).
Ping-Pong Playback (Godot 4.7+)
`SpriteFrames` gains a `LoopMode` enum — `LOOP_NONE = 0`, `LOOP_LINEAR = 1`, `LOOP_PINGPONG = 2` — set per anim
Read more
name: animation-system description: Use when implementing animations — AnimationPlayer, AnimationTree, blend trees, state machines, sprite animation, and code-driven animation
Animation System in Godot 4.3+
All examples target Godot 4.3+ with no deprecated APIs. GDScript is shown first, then C#.
> **Related skills:** **state-machine** for gameplay state management, **player-controller** for movement that drives animation, **component-system** for reusable animation components, **2d-essentials** for TileMaps, parallax scrolling, 2D lights, and canvas layer organization, **3d-essentials** for AnimationTree and 3D animation blending, **shader-basics** for shader-driven hit flash and dissolve effects, **tween-animation** for code-driven motion alongside keyframe animation.
---
1. Core Concepts
AnimationPlayer vs AnimationTree
| Node | Use For | Complexity | Notes | |-------------------|------------------------------------------|------------|----------------------------------------------------| | `AnimationPlayer` | Simple playback, one-shot effects | Low | Play/stop/queue individual clips directly | | `AnimationTree` | Blending, transitions, layered animation | Medium-High| State machines and blend trees for smooth transitions |
**Rule of thumb:** Start with AnimationPlayer. Add AnimationTree when you need blending between animations (walk/run blend, directional movement, layered upper/lower body).
Animation Workflow
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 Basics
Scene Structure
Character (CharacterBody2D) ├── Sprite2D └── AnimationPlayer
AnimationPlayer can animate **any property** on any sibling or child node: sprite frames, modulate, position, rotation, scale, visibility, collision shape disabled state, method calls (Call Method track), audio playback (Audio Playback track).
GDScript — Basic Playback
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# — Basic Playback
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();
}
}> Calling `play()` with the same animation name while it's already playing does nothing (no restart). This is safe to call every frame.
Playback Control
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. Animation Signals
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();
}Method Call Tracks
Add a **Call Method** track to trigger game logic at exact animation frames (spawn projectile at frame 5, play SFX at impact frame, enable hitbox during swing). In the Animation panel: Add Track → Call Method Track → select target node → add keyframes → set method name and arguments.
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. Sprite Frame Animation
Two approaches for 2D character animation: `AnimatedSprite2D` (quick, frames-only) and `AnimationPlayer + Sprite2D` (full property animation). Pick AnimatedSprite2D for simple characters; AnimationPlayer when you also animate hitboxes, particles, sounds, or other properties in sync.
> See [references/sprite-animation.md](references/sprite-animation.md) for the full GDScript and C# example (a CharacterBody2D walking with `AnimatedSprite2D` driven by `Input.get_vector` and `flip_h`).
Ping-Pong Playback (Godot 4.7+)
`SpriteFrames` gains a `LoopMode` enum — `LOOP_NONE = 0`, `LOOP_LINEAR = 1`, `LOOP_PINGPONG = 2` — set per anim
Agentic skills framework for Godot 4.x game development. Gives AI coding agents domain-specific expertise for GDScript and C# projects.
Other skills on godot-prompter.
- /authoring-godot-prompter-skills
Use when writing or editing a SKILL.md or an agent definition in this repo — required frontmatter, section ordering, and the GDScript-then-C# example convention.
Open skill - /releasing-godot-prompter
Use when cutting a GodotPrompter release or bumping its version — the version-bump sequence, tag-triggered workflow, and the marketplace manifests that must follow.
Open skill - /2d-essentials
Use when working with 2D-specific systems — TileMaps, parallax scrolling, 2D lights and shadows, canvas layers, particles 2D, custom drawing, and 2D meshes in Godot 4.3+
Open skill - /3d-essentials
Use when working with 3D-specific systems — materials, lighting, shadows, environment, global illumination, fog, LOD, occlusion culling, and decals in Godot 4.3+
Open skill - /ability-system
Use when building character abilities — Resource-based abilities with cost/cooldown/cast, buffs/debuffs, stat modifiers, gameplay tags, and HUD binding
Open skill - /addon-development
Use when creating Godot editor plugins — EditorPlugin, @tool scripts, custom inspectors, and dock panels
Open skill

