Animation: AnimationPlayer, AnimationTree & Tweens
AnimationPlayer can keyframe any property of any node (position, modulate, frame, shader parameters), call methods, play audio, and more.
22.1 AnimationPlayer
AnimationPlayer can keyframe any property of any node (position, modulate, frame, shader parameters), call methods, play audio, and more. Create animations in the Animation bottom panel.
Other members: play_backwards(), stop(), pause(), seek(time), current_animation, is_playing(), get_animation("walk").length, has_animation(). Use Call Method tracks to trigger code (spawn a hitbox on frame 5) and set RESET animations for default values.
@onready var anim: AnimationPlayer = $AnimationPlayer
func _ready() -> void:
anim.play("idle")
anim.animation_finished.connect(_on_animation_finished)
func attack() -> void:
anim.play("attack")
anim.queue("idle") # play after the current one
anim.speed_scale = 1.5
func _on_animation_finished(anim_name: StringName) -> void:
if anim_name == &"death":
queue_free()22.2 AnimatedSprite2D (frame-by-frame)
Frames are stored in a SpriteFrames resource.
$AnimatedSprite2D.play("run")
$AnimatedSprite2D.flip_h = true
$AnimatedSprite2D.animation_finished.connect(...)
$AnimatedSprite2D.frame_changed.connect(...)22.3 AnimationTree
AnimationTree blends animations from an AnimationPlayer using a graph: state machines, blend spaces (1D/2D), blend nodes.
In Godot 4.2+, AnimationPlayer and AnimationTree both inherit AnimationMixer (shared libraries, root motion).
@onready var tree: AnimationTree = $AnimationTree
@onready var playback: AnimationNodeStateMachinePlayback = tree["parameters/playback"]
func _physics_process(_delta: float) -> void:
var input := Input.get_vector("move_left", "move_right", "move_up", "move_down")
if input != Vector2.ZERO:
tree.set("parameters/Idle/blend_position", input) # BlendSpace2D inside state "Idle"
tree.set("parameters/Walk/blend_position", input)
playback.travel("Walk") # path-finds through the state machine
else:
playback.travel("Idle")
tree.set("parameters/conditions/is_dead", health <= 0) # transition condition22.4 Tweens
Tweens animate properties from code — perfect for UI, juice, and one-off effects.
tween_property(obj, path, final, duration) Animate a property
.from(value) / .from_current() / .as_relative() / .set_delay(s) Property tweener options Call a function
tween_method(callable, from, to, duration) Call a method with interpolated values set_trans() / set_ease()
Curves: LINEAR, SINE, QUAD, CUBIC, BACK, ELASTIC, BOUNCE...
set_parallel(), parallel(), chain() Sequential vs parallel
set_loops(n), kill(), pause(), play(), is_running()
A node-bound tween (node.create_tween()) stops automatically when the node is freed. Kill a previous tween before starting a new one on the same property:
Godot 3 note: the Tween node with interpolate_property() + start() was replaced by create_tween().
func pop_in() -> void:
scale = Vector2.ZERO
var tween := create_tween()
tween.tween_property(self, "scale", Vector2.ONE, 0.4)\
.set_trans(Tween.TRANS_BACK).set_ease(Tween.EASE_OUT)
func flash_and_die() -> void:
var tween := create_tween()
tween.tween_property(self, "modulate", Color.RED, 0.1)
tween.tween_property(self, "modulate", Color.WHITE, 0.1)
tween.tween_property(self, "modulate:a", 0.0, 0.3) # subproperty path
tween.tween_callback(queue_free) # call at the end
await tween.finished
func move_parallel() -> void:
var tween := create_tween().set_parallel(true)
tween.tween_property(self, "position", Vector2(300, 200), 1.0)
tween.tween_property(self, "rotation", TAU, 1.0)
tween.chain().tween_interval(0.5) # back to sequential
tween.tween_method(set_label_value, 0, 100, 1.0) # animate a method argument
func bob_forever() -> void:
var tween := create_tween().set_loops() # infinite loop
tween.tween_property($Sprite2D, "position:y", -8.0, 0.5).as_relative()
tween.tween_property($Sprite2D, "position:y", 8.0, 0.5).as_relative()var _tween: Tween
func fade_to(alpha: float) -> void:
if _tween: _tween.kill()
_tween = create_tween()
_tween.tween_property(self, "modulate:a", alpha, 0.25)