Skills/godot-animation/SKILL.md

9.1 KiB

name description license compatibility metadata
godot-animation Animation systems for Godot 4.x: AnimationPlayer vs AnimationTree, state machines, blend spaces (1D/2D/directional), animation libraries, root motion, collapsible tracks, and tween_await(). Use when building character animations, cutscenes, or visual effects in Godot. MIT
godot-4.0
godot-4.1
godot-4.2
godot-4.3
godot-4.4
godot-4.5
godot-4.6
godot-4.7
author version tags created
vl4dt 0.1.0
godot
animation
animationplayer
animationtree
blend-space
root-motion
2026-06-20

Animation Systems for Godot 4.x

Comprehensive patterns for character animation, state machines, and visual effects in Godot 4.x.

AnimationPlayer vs AnimationTree

AnimationPlayer — Simple Animations

Use AnimationPlayer for linear sequences, cutscenes, and simple property animations.

@onready var anim_player = $AnimationPlayer

func play_attack():
    anim_player.play("attack")

func play_transition(target: String, fade_time: float = 0.2):
    anim_player.play(target, fade_time)

# Signal-based animation completion
func _ready():
    anim_player.animation_finished.connect(_on_animation_finished)

func _on_animation_finished(anim_name: String):
    if anim_name == "attack":
        print("Attack animation complete")

AnimationTree — State Machine Animations

Use AnimationTree for complex character animations with branching states (idle, walk, run, jump).

@onready var anim_tree = $AnimationTree
@onready var anim_state = anim_tree.get("state_machine")

func _ready():
    anim_state.travel("Idle")  # Start at Idle state

func set_animation(state_name: String):
    if anim_state.has_state(state_name):
        anim_state.travel(state_name)

func _physics_process(delta: float):
    var speed = velocity.length()
    anim_tree.set("parameters/Move/speed", speed)
    anim_tree.process(delta)

When to Use Which

Use Case Tool
Cutscenes, UI animations AnimationPlayer
Character movement states AnimationTree + StateMachine
Simple one-shot effects AnimationPlayer
Blending between movements AnimationTree + BlendSpace2D
Complex combat combos AnimationTree + AnimationNodeBlendTree

State Machines in AnimationTree

Building a Character State Machine

# In the AnimationTree, create an AnimationNodeStateMachine:
# States: Idle, Walk, Run, Jump, Fall, Attack
# Transitions: Idle <-> Walk, Idle <-> Run, Walk -> Run, etc.

@onready var anim_tree = $AnimationTree
@onready var state_machine = anim_tree.get("state_machine")

func _physics_process(delta: float):
    var speed = velocity.length()
    var new_state = "Idle"
    
    if not is_on_floor():
        new_state = "Fall" if velocity.y < 0 else "Jump"
    elif speed > 0.1:
        new_state = "Run" if speed > run_threshold else "Walk"
    
    # Only transition if the target state exists
    if state_machine.has_state(new_state):
        state_machine.travel(new_state)
    
    anim_tree.set("parameters/Move/speed", speed)
    anim_tree.process(delta)

Transition Conditions

Set transition conditions in the AnimationTree editor:

  • Blend: Use blend amounts based on parameters (e.g., speed)
  • One Shot: Play once then return (for attacks, interactions)
  • Transition Rules: Define when transitions are allowed

Blend Spaces

1D Blend Space

Use for animations ordered along a single axis (e.g., walk speed).

# AnimationTree setup:
# BlendSpace1D: Walk -> Run -> Sprint
# Parameter: "speed" (float)

anim_tree.set("parameters/BlendSpace1D/speed", current_speed)

2D Blend Space

Use for directional movement blending.

# AnimationTree setup:
# BlendSpace2D: X = speed, Y = direction blend
# Parameters: "speed" and "direction"

anim_tree.set("parameters/BlendSpace2D/speed", velocity.length())
anim_tree.set("parameters/BlendSpace2D/direction", velocity.angle())

Directional Blend Space (Godot 4.x)

Use a directional blend for 8-directional character animations.

# Set up AnimationNodeBlendDBone2D for directional blending
@onready var anim_tree = $AnimationTree

func _physics_process(delta: float):
    var dir = velocity.normalized()
    anim_tree.set("parameters/Directional/speed", velocity.length())
    anim_tree.set("parameters/Directional/direction", dir)
    anim_tree.process(delta)

Animation Libraries and Blending Tracks

Animation Libraries

Group related animations into libraries for organization.

# Access library animations by name
@onready var anim_player = $AnimationPlayer

func play_animation(anim_name: String):
    # Animations are organized by library in the editor
    anim_player.play(anim_name)

# List available animations
func get_available_animations() -> Array:
    return anim_player.get_animation_list()

Blending Tracks

Blend between multiple animation tracks for smooth transitions.

# Set blend amount in AnimationTree
anim_tree.set("parameters/Idle/blend_amount", 1.0)

# Blend between two animations
anim_player.play("idle", -1.0, 1.0)  # loop, 1s fade-in
anim_player.play("walk", -1.0, 0.5)  # loop, 0.5s fade-in

# Crossfade by playing both simultaneously
# The AnimationTree blend space handles the mixing

Root Motion for Character Movement

Using Root Motion in AnimationTree

Root motion applies bone animation directly to the character transform.

class_name RootMotionCharacter extends CharacterBody3D

@onready var anim_tree = $AnimationTree
@onready var anim_state = anim_tree.get("state_machine")

@export var root_motion_enabled: bool = true

func _physics_process(delta: float):
    # Calculate root motion displacement
    var prev_transform = global_transform
    
    # Process animation tree (applies root motion)
    anim_tree.process(delta)
    
    if root_motion_enabled:
        var root_delta = global_transform.xform_inv(prev_transform)
        velocity = Vector3(root_delta.origin.x / delta, 0, root_delta.origin.z / delta)
    else:
        # Use scripted movement instead
        velocity = transform.basis.z * speed
    
    move_and_slide()

When to Use Root Motion

  • Platformer jump arcs (precise landing positions)
  • Attack animations with fixed reach distances
  • Cutscene character movements

When to Avoid Root Motion

  • Multiplayer games (server authority conflicts)
  • Characters that need precise position control
  • Games with custom physics responses

Godot 4.7 Animation Features

Collapsible Animation Tracks

Godot 4.7 introduces collapsible animation tracks for better organization in the AnimationPlayer editor.

# No code change needed — this is an editor feature
# In the AnimationPlayer inspector, click track headers to collapse/expand
# Group related properties under collapsible sections

tween_await() for Sequential Animations

Use await with tweens for clean sequential animation chains.

func play_combo_animation():
    # Chain animations without nested callbacks
    await create_tween().tween_property($Sprite, "offset:x", 10.0, 0.1).finished
    await create_tween().tween_property($Sprite, "offset:x", 0.0, 0.1).finished
    print("Combo animation complete")

# Or with AnimationPlayer
func play_with_wait():
    var tween = create_tween()
    anim_player.play("attack")
    await tween.tween_interval(0.5)
    anim_player.play("recovery")

Animation Performance Tips

  • Use AnimationTree with state machines instead of multiple AnimationPlayers
  • Keep animation libraries small and focused
  • Use AnimationNodeSync to synchronize multiple character animations
  • Preload animation resources with preload() for always-needed scenes
  • Avoid animating properties that can be set directly (e.g., position vs tween)
  • Use animation_finished signal instead of polling for completion

Quick Reference: Animation Methods

Method Use Case
anim_player.play(name) Start an animation
anim_player.play(name, fade_time) Crossfade to animation
anim_tree.process(delta) Update state machine
anim_tree.set("params/...", value) Set blend parameters
state_machine.travel(name) Switch to a state
create_tween() Create animation tweens
await tween.finished Wait for tween completion

MCP Bridge Tools (Optional — Live Editor Integration)

When the MCP bridge is running (Phase 2), these tools enhance animation debugging:

  • animation_play — Play any animation from the project without opening the editor
  • animation_list — List all available animations and their libraries
  • animation_state_get — Query current AnimationTree state machine status
  • animation_preview_frame — Preview a specific frame of any animation

Note: MCP tools require the Godot editor to be running with the MCP plugin enabled. Skills work independently without the bridge.

References