Godot Animation (4.x)
Choose and drive the right animation tool: AnimationPlayer (clips), AnimationTree
(blending/state machines), or Tween (short procedural moves). Targets Godot 4.7.
When to use
- Use when playing keyframed animations, blending walk/run/idle states, animating a
sprite sheet, or tweening UI/objects in code.
When not to use: the movement logic that decides which state to play →
godot-2d-movement; UI layout (vs. UI tweening) → godot-ui-control; shader-driven
effects → godot-shaders.
Core workflow
- Pick the tool:
AnimationPlayer — author keyframed clips (transforms, properties, method calls,
audio, even other animations). The source of truth for clip data.
AnimationTree — blend and transition between those clips at runtime with a state
machine and/or blend spaces. Needs an AnimationPlayer to pull clips from.
Tween — fire-and-forget procedural interpolation in code (create_tween()); ideal
for UI pops, fades, and one-off moves.
- For 2D sprite sheets: use
AnimatedSprite2D + SpriteFrames, or keyframe the
frame property in an AnimationPlayer.
- For characters: build clips in
AnimationPlayer, then add an AnimationTree
(active = true), set its anim_player, and design an AnimationNodeStateMachine or
AnimationNodeBlendSpace2D as the tree root.
- Drive transitions from code via the playback object (
travel) or by setting blend
parameters.
- React to clip events with the
animation_finished signal and call/method tracks.
Patterns
1. AnimationPlayer: play a clip and await it
@onready var anim: AnimationPlayer = $AnimationPlayer
func attack() -> void:
anim.play("attack")
await anim.animation_finished # resume after the clip ends
anim.play("idle")
2. AnimationTree state machine: travel between states
@onready var tree: AnimationTree = $AnimationTree
func _ready() -> void:
tree.active = true # the tree drives animation; AnimationPlayer is the source
func set_state(state: StringName) -> void:
# The playback object controls an AnimationNodeStateMachine root.
var sm: AnimationNodeStateMachinePlayback = tree.get("parameters/playback")
sm.travel(state) # transitions using the graph's connections
func _physics_process(_d: float) -> void:
set_state(&"run" if velocity.length() > 5.0 else &"idle")
3. Blend space: blend run direction by a 2D parameter
# Root is an AnimationNodeBlendSpace2D named "Move" with idle/run points placed in it.
func update_locomotion(input_dir: Vector2) -> void:
# Parameter path = "parameters/<node name>/blend_position".
tree.set("parameters/Move/blend_position", input_dir)
4. Tween: fade and scale a UI element (code-driven)
func pop_in(node: Control) -> void:
node.scale = Vector2.ZERO
node.modulate.a = 0.0
var tw := create_tween() # bound to this node's tree
tw.set_parallel(true) # run the two tweens together
tw.tween_property(node, "scale", Vector2.ONE, 0.2) \
.set_trans(Tween.TRANS_BACK).set_ease(Tween.EASE_OUT)
tw.tween_property(node, "modulate:a", 1.0, 0.2) # sub-property via ":"
Pitfalls
AnimationTree.active left false → nothing animates and travel() appears to do
nothing. Set active = true and assign the anim_player path.
- Wrong parameter path. Blend/condition paths are
"parameters/<NodeName>/..." and
must match the node names in the tree exactly (e.g. "parameters/playback",
"parameters/Move/blend_position"). A typo silently no-ops.
- AnimationPlayer and AnimationTree fighting. When an
AnimationTree is active, don't
also call AnimationPlayer.play() for the same tracks — let the tree own playback.
- 3.x Tween node is gone. There is no
Tween node to add in 4.x; create tweens in
code with create_tween() (which returns a Tween). They auto-start and free themselves.
- Reusing a finished tween. A tween is one-shot; call
create_tween() again for a new
animation. Use set_loops() for repetition.
yield/yield(anim, "...") is gone. Use await anim.animation_finished.
- Sub-property tweens use a colon:
"modulate:a", "position:x". Tweening the whole
property instead overwrites siblings.
References
- For state machine transitions/conditions, root motion, one-shot/blend nodes, method &
call tracks,
SpriteFrames/AnimatedSprite2D, and Tween easing/chaining/callbacks,
read references/animation-tree-and-tween.md.
Related skills
godot-2d-movement — supplies the velocity/state that selects animations.
godot-ui-control — UI that Tweens animate.
godot-3d-essentials — 3D character scenes driven by AnimationTree.
game-ai — state machines that mirror animation states.
1---2name: godot-animation3description: Animate in Godot 4.7 three ways: AnimationPlayer for keyframed clips (incl. call and signal tracks), AnimationTree with state machines and blend spaces for character animation, and Tween for short procedural/UI tweens via create_tween(). Use when working with AnimationPlayer/AnimationTree nodes in a .tscn, blending character states, sprite-sheet animation, or code-driven Tweens.4---5
6# Godot Animation (4.x)
7
8Choose and drive the right animation tool: `AnimationPlayer` (clips), `AnimationTree`
9(blending/state machines), or `Tween` (short procedural moves). Targets **Godot 4.7**.
10
11## When to use
12
13- Use when playing keyframed animations, blending walk/run/idle states, animating a
14 sprite sheet, or tweening UI/objects in code.
15
16**When *not* to use:** the movement *logic* that decides which state to play →
17`godot-2d-movement`; UI layout (vs. UI tweening) → `godot-ui-control`; shader-driven
18effects → `godot-shaders`.
19
20## Core workflow
21
221. **Pick the tool:**
23 - `AnimationPlayer` — author keyframed clips (transforms, properties, method calls,
24 audio, even other animations). The source of truth for clip data.
25 - `AnimationTree` — blend and transition between those clips at runtime with a state
26 machine and/or blend spaces. Needs an `AnimationPlayer` to pull clips from.
27 - `Tween` — fire-and-forget procedural interpolation in code (`create_tween()`); ideal
28 for UI pops, fades, and one-off moves.
292. **For 2D sprite sheets:** use `AnimatedSprite2D` + `SpriteFrames`, or keyframe the
30 `frame` property in an `AnimationPlayer`.
313. **For characters:** build clips in `AnimationPlayer`, then add an `AnimationTree`
32 (`active = true`), set its `anim_player`, and design an `AnimationNodeStateMachine` or
33 `AnimationNodeBlendSpace2D` as the tree root.
344. **Drive transitions from code** via the playback object (`travel`) or by setting blend
35 parameters.
365. **React to clip events** with the `animation_finished` signal and call/method tracks.
37
38## Patterns
39
40### 1. AnimationPlayer: play a clip and await it
41
42```gdscript
43@onready var anim: AnimationPlayer = $AnimationPlayer
44
45func attack() -> void:
46 anim.play("attack")
47 await anim.animation_finished # resume after the clip ends
48 anim.play("idle")
49```
50
51### 2. AnimationTree state machine: travel between states
52
53```gdscript
54@onready var tree: AnimationTree = $AnimationTree
55
56func _ready() -> void:
57 tree.active = true # the tree drives animation; AnimationPlayer is the source
58
59func set_state(state: StringName) -> void:
60 # The playback object controls an AnimationNodeStateMachine root.
61 var sm: AnimationNodeStateMachinePlayback = tree.get("parameters/playback")
62 sm.travel(state) # transitions using the graph's connections
63
64func _physics_process(_d: float) -> void:
65 set_state(&"run" if velocity.length() > 5.0 else &"idle")
66```
67
68### 3. Blend space: blend run direction by a 2D parameter
69
70```gdscript
71# Root is an AnimationNodeBlendSpace2D named "Move" with idle/run points placed in it.
72func update_locomotion(input_dir: Vector2) -> void:
73 # Parameter path = "parameters/<node name>/blend_position".
74 tree.set("parameters/Move/blend_position", input_dir)
75```
76
77### 4. Tween: fade and scale a UI element (code-driven)
78
79```gdscript
80func pop_in(node: Control) -> void:
81 node.scale = Vector2.ZERO
82 node.modulate.a = 0.0
83 var tw := create_tween() # bound to this node's tree
84 tw.set_parallel(true) # run the two tweens together
85 tw.tween_property(node, "scale", Vector2.ONE, 0.2) \
86 .set_trans(Tween.TRANS_BACK).set_ease(Tween.EASE_OUT)
87 tw.tween_property(node, "modulate:a", 1.0, 0.2) # sub-property via ":"
88```
89
90## Pitfalls
91
92- **`AnimationTree.active` left false** → nothing animates and `travel()` appears to do
93 nothing. Set `active = true` and assign the `anim_player` path.
94- **Wrong parameter path.** Blend/condition paths are `"parameters/<NodeName>/..."` and
95 must match the node names in the tree exactly (e.g. `"parameters/playback"`,
96 `"parameters/Move/blend_position"`). A typo silently no-ops.
97- **AnimationPlayer and AnimationTree fighting.** When an `AnimationTree` is active, don't
98 also call `AnimationPlayer.play()` for the same tracks — let the tree own playback.
99- **3.x Tween node is gone.** There is no `Tween` node to add in 4.x; create tweens in
100 code with `create_tween()` (which returns a `Tween`). They auto-start and free themselves.
101- **Reusing a finished tween.** A tween is one-shot; call `create_tween()` again for a new
102 animation. Use `set_loops()` for repetition.
103- **`yield`/`yield(anim, "...")` is gone.** Use `await anim.animation_finished`.
104- **Sub-property tweens** use a colon: `"modulate:a"`, `"position:x"`. Tweening the whole
105 property instead overwrites siblings.
106
107## References
108
109- For state machine transitions/conditions, root motion, one-shot/blend nodes, method &
110 call tracks, `SpriteFrames`/`AnimatedSprite2D`, and Tween easing/chaining/callbacks,
111 read `references/animation-tree-and-tween.md`.
112
113## Related skills
114
115- `godot-2d-movement` — supplies the velocity/state that selects animations.
116- `godot-ui-control` — UI that Tweens animate.
117- `godot-3d-essentials` — 3D character scenes driven by AnimationTree.
118- `game-ai` — state machines that mirror animation states.