Skip to main content
The AnimationPlayer node is the primary way to play and control animations in Godot. It manages animation playback, blending between animations, and provides extensive control over timing and playback.

Creating an AnimationPlayer

Add an AnimationPlayer node to your scene:
1

Add the node

In the Scene dock, right-click your node and select “Add Child Node”, then search for AnimationPlayer.
2

Create animations

With the AnimationPlayer selected, use the Animation panel at the bottom to create new animations.
3

Add tracks

Click “Add Track” to animate properties of nodes in your scene.

Basic Playback

The AnimationPlayer provides simple methods for controlling animation playback:
# Play an animation
$AnimationPlayer.play("walk")

# Play with custom speed (2x speed)
$AnimationPlayer.play("walk", -1, 2.0)

# Play backwards
$AnimationPlayer.play_backwards("run")

# Pause the current animation
$AnimationPlayer.pause()

# Stop and reset
$AnimationPlayer.stop()

Play Method Parameters

The play() method accepts several parameters:
  • name: Animation name to play (empty uses assigned animation)
  • custom_blend: Blend time in seconds (default uses playback_default_blend_time)
  • custom_speed: Speed multiplier (negative values play backwards)
  • from_end: Start from the end of the animation

Animation Properties

Current Animation

# Get currently playing animation
var current = $AnimationPlayer.current_animation
print("Playing: ", current)

# Set current animation (doesn't auto-play)
$AnimationPlayer.current_animation = "idle"

# Get assigned animation
var assigned = $AnimationPlayer.assigned_animation
current_animation changes the animation but doesn’t play it unless already playing. Use play() to start playback.

Playback State

# Check if playing
if $AnimationPlayer.is_playing():
    print("Animation is active")

# Get playback position
var position = $AnimationPlayer.current_animation_position
print("Current time: ", position)

# Get animation length
var length = $AnimationPlayer.current_animation_length
print("Total duration: ", length)

# Get actual playing speed (speed_scale × custom_speed)
var speed = $AnimationPlayer.get_playing_speed()

Animation Blending

One of AnimationPlayer’s most powerful features is smooth blending between animations.

Default Blend Time

# Set default blend time for all transitions
$AnimationPlayer.playback_default_blend_time = 0.2

# Now all animations blend smoothly over 0.2 seconds
$AnimationPlayer.play("walk")
await get_tree().create_timer(1.0).timeout
$AnimationPlayer.play("run")  # Blends from walk to run

Custom Blend Times

Set specific blend times between particular animations:
# Blend from "idle" to "walk" over 0.3 seconds
$AnimationPlayer.set_blend_time("idle", "walk", 0.3)

# Blend from "walk" to "run" over 0.1 seconds
$AnimationPlayer.set_blend_time("walk", "run", 0.1)

# Blend from "run" to "idle" over 0.5 seconds
$AnimationPlayer.set_blend_time("run", "idle", 0.5)

# Play with automatic blending
$AnimationPlayer.play("walk")  # Uses custom blend time

Manual Blend Override

# Override blend time for a specific play() call
$AnimationPlayer.play("jump", 0.1)  # Blend over 0.1 seconds

Speed Control

Control animation playback speed globally or per-animation:
# Global speed multiplier
$AnimationPlayer.speed_scale = 1.5  # 1.5x speed

# Slow motion effect
$AnimationPlayer.speed_scale = 0.5  # Half speed

# Play specific animation at custom speed
$AnimationPlayer.play("attack", -1, 2.0)  # 2x speed

# Reverse playback
$AnimationPlayer.speed_scale = -1.0  # Play backwards
The actual playing speed is speed_scale × custom_speed. Use get_playing_speed() to get the combined value.

Seeking and Sections

Seeking to a Position

# Seek to 1.5 seconds
$AnimationPlayer.seek(1.5)

# Seek and update immediately
$AnimationPlayer.seek(1.5, true)

# Seek without processing method/audio tracks
$AnimationPlayer.seek(1.5, true, true)

Playing Animation Sections

Play only part of an animation:
# Play from 0.5 to 2.0 seconds
$AnimationPlayer.play_section("walk", 0.5, 2.0)

# Play section using markers
$AnimationPlayer.play_section_with_markers("cutscene", "start", "end")

# Update section boundaries while playing
$AnimationPlayer.set_section(1.0, 3.0)

# Reset to play full animation
$AnimationPlayer.reset_section()

Animation Queue

Queue animations to play in sequence:
# Play current animation, then queue others
$AnimationPlayer.play("attack")
$AnimationPlayer.queue("idle")

# Check the queue
var queued = $AnimationPlayer.get_queue()
print("Queued animations: ", queued)

# Clear the queue
$AnimationPlayer.clear_queue()

Auto-Advance

Automatically play another animation when one finishes:
# When "attack" finishes, automatically play "idle"
$AnimationPlayer.animation_set_next("attack", "idle")

# Get the next animation
var next = $AnimationPlayer.animation_get_next("attack")
print("After attack, plays: ", next)

Auto-Capture

Auto-capture smoothly transitions from the current state to the animation:
# Enable auto-capture
$AnimationPlayer.playback_auto_capture = true
$AnimationPlayer.playback_auto_capture_duration = 0.3

# Or use play_with_capture for manual control
$AnimationPlayer.play_with_capture("jump", 0.2, -1, 1.0, false, 
    Tween.TRANS_CUBIC, Tween.EASE_OUT)
Auto-capture is useful when objects are procedurally animated or affected by physics, ensuring smooth transitions to keyframed animations.

Autoplay

Set an animation to play automatically when the scene starts:
# In the editor: Select AnimationPlayer → Autoplay property
# Or in code:
$AnimationPlayer.autoplay = "idle"

Signals

AnimationPlayer provides signals for animation events:
func _ready():
    $AnimationPlayer.animation_finished.connect(_on_animation_finished)
    $AnimationPlayer.animation_changed.connect(_on_animation_changed)

func _on_animation_finished(anim_name):
    print("Finished playing: ", anim_name)
    
func _on_animation_changed(old_name, new_name):
    print("Changed from ", old_name, " to ", new_name)

Advanced Features

Movie Quit on Finish

Useful for rendering animations:
# Quit when animation finishes (for Movie Maker mode)
$AnimationPlayer.movie_quit_on_finish = true

Manual Advancement

# Manually advance animation by delta time
$AnimationPlayer.advance(0.016)  # Advance by 1 frame at 60 FPS

Complete Example

Here’s a complete character animation controller:
extends CharacterBody2D

func _ready():
    # Setup blend times
    $AnimationPlayer.set_blend_time("idle", "walk", 0.2)
    $AnimationPlayer.set_blend_time("walk", "run", 0.15)
    $AnimationPlayer.set_blend_time("run", "idle", 0.3)
    
    # Auto-play idle
    $AnimationPlayer.play("idle")

func _physics_process(delta):
    var velocity_length = velocity.length()
    
    if velocity_length > 200:
        if $AnimationPlayer.current_animation != "run":
            $AnimationPlayer.play("run")
    elif velocity_length > 10:
        if $AnimationPlayer.current_animation != "walk":
            $AnimationPlayer.play("walk")
    else:
        if $AnimationPlayer.current_animation != "idle":
            $AnimationPlayer.play("idle")

Next Steps

AnimationTree

Create complex animation blending with state machines

Skeletal Animation

Animate 3D characters with bones and IK

Build docs developers (and LLMs) love