GDScript Tweens Cheat Sheet
Quick-reference for Godot 4 tween animations. Each section includes copy-ready snippets with inline output comments for UI polish and game effects.
Creating Tweens
In Godot 4, create tweens with create_tween(). The old Tween node is removed — do not use Tween.new().
var tween := create_tween()
# tween is bound to this node — auto-killed when node exits treevar tween := get_tree().create_tween()
# This tween survives node removal — use for scene transitionsvar active_tween: Tween
func flash() -> void:
# Kill any running tween to avoid stacking
if active_tween and active_tween.is_running():
active_tween.kill()
active_tween = create_tween()
active_tween.tween_property(self, "modulate", Color.RED, 0.1)
active_tween.tween_property(self, "modulate", Color.WHITE, 0.1)Always kill() an existing tween before creating a new one on the same property to prevent conflicts.
tween_property()
Animate any node property from its current value to a target over a duration.
var tween := create_tween()
tween.tween_property($Sprite2D, "modulate:a", 0.0, 0.5)
# Fades alpha from current to 0 over 0.5 secondsvar tween := create_tween()
tween.tween_property(self, "position", Vector2(500, 300), 1.0)var tween := create_tween()
tween.tween_property($Coin, "scale", Vector2(1.5, 1.5), 0.15)
tween.tween_property($Coin, "scale", Vector2(1.0, 1.0), 0.15)var tween := create_tween()
tween.tween_property($Label, "modulate:a", 1.0, 0.3).from(0.0)
# Forces start at 0, animate to 1 (fade in)tween_callback() and tween_interval()
Insert function calls and delays into a tween sequence.
var tween := create_tween()
tween.tween_property(self, "position:y", -50.0, 0.3)
tween.tween_callback(queue_free) # remove after animationvar tween := create_tween()
tween.tween_property(self, "modulate", Color.RED, 0.1)
tween.tween_interval(0.5) # wait 0.5 seconds
tween.tween_property(self, "modulate", Color.WHITE, 0.1)var tween := create_tween()
tween.tween_callback(emit_signal.bind("death_finished"))
# Or with a lambda:
tween.tween_callback(func(): print("Animation done!"))Sequential vs Parallel Tweens
By default, tween steps run sequentially. Use set_parallel() or parallel() to run them simultaneously.
var tween := create_tween()
# Step 1: move right
tween.tween_property(self, "position:x", 500.0, 1.0)
# Step 2: then fade out (starts AFTER move finishes)
tween.tween_property(self, "modulate:a", 0.0, 0.5)var tween := create_tween()
tween.set_parallel(true)
# Both run simultaneously:
tween.tween_property(self, "position:x", 500.0, 1.0)
tween.tween_property(self, "modulate:a", 0.0, 1.0)var tween := create_tween()
# Step 1: move and fade at the same time
tween.tween_property(self, "position:x", 500.0, 0.5)
tween.parallel().tween_property(self, "modulate:a", 0.0, 0.5)
# Step 2: then call cleanup (sequential after both finish)
tween.tween_callback(queue_free).parallel() makes just that one step parallel with the previous. The next step is sequential again.
Easing and Transitions
Control the animation curve with set_ease() and set_trans(). These make animations feel polished.
var tween := create_tween()
# Smooth start (accelerate)
tween.tween_property(self, "position:y", 0.0, 0.5) \
.set_ease(Tween.EASE_IN)
# Smooth end (decelerate)
tween.tween_property(self, "position:y", 0.0, 0.5) \
.set_ease(Tween.EASE_OUT)
# Smooth both (most natural)
tween.tween_property(self, "position:y", 0.0, 0.5) \
.set_ease(Tween.EASE_IN_OUT)# Bounce effect — item lands and bounces
tween.tween_property($Item, "position:y", 400.0, 0.6) \
.set_trans(Tween.TRANS_BOUNCE).set_ease(Tween.EASE_OUT)
# Elastic — springy overshoot (great for UI)
tween.tween_property($Panel, "scale", Vector2.ONE, 0.4) \
.set_trans(Tween.TRANS_ELASTIC).set_ease(Tween.EASE_OUT)
# Back — slight overshoot then settle
tween.tween_property($Button, "position:x", 200.0, 0.3) \
.set_trans(Tween.TRANS_BACK).set_ease(Tween.EASE_OUT)var tween := create_tween()
tween.set_ease(Tween.EASE_OUT)
tween.set_trans(Tween.TRANS_CUBIC)
# All subsequent steps use these defaults
tween.tween_property(self, "position", target_pos, 0.5)
tween.tween_property(self, "rotation", target_rot, 0.5)Looping Tweens
Use set_loops() to repeat tween sequences. Pass 0 for infinite loops.
var tween := create_tween()
tween.set_loops() # 0 = infinite
tween.tween_property($Item, "position:y", -10.0, 0.5) \
.set_ease(Tween.EASE_IN_OUT).set_trans(Tween.TRANS_SINE).as_relative()
tween.tween_property($Item, "position:y", 10.0, 0.5) \
.set_ease(Tween.EASE_IN_OUT).set_trans(Tween.TRANS_SINE).as_relative()var tween := create_tween()
tween.set_loops(3)
tween.tween_property($Sprite, "modulate:a", 0.3, 0.15)
tween.tween_property($Sprite, "modulate:a", 1.0, 0.15)var tween := create_tween()
tween.set_loops()
tween.tween_property($Icon, "scale", Vector2(1.1, 1.1), 0.4) \
.set_ease(Tween.EASE_IN_OUT).set_trans(Tween.TRANS_SINE)
tween.tween_property($Icon, "scale", Vector2(1.0, 1.0), 0.4) \
.set_ease(Tween.EASE_IN_OUT).set_trans(Tween.TRANS_SINE)Tween Control
Pause, resume, kill, and check tween state.
var tween: Tween
func start_effect() -> void:
if tween and tween.is_running():
tween.kill()
tween = create_tween()
tween.tween_property(self, "modulate:a", 0.0, 1.0)
func cancel_effect() -> void:
if tween and tween.is_running():
tween.kill()
modulate.a = 1.0 # reset to defaultvar tween: Tween
func _ready() -> void:
tween = create_tween()
tween.tween_property(self, "position:x", 1000.0, 5.0)
func on_game_paused() -> void:
if tween and tween.is_valid():
tween.pause()
func on_game_resumed() -> void:
if tween and tween.is_valid():
tween.play()func slide_in_panel() -> void:
var tween := create_tween()
tween.tween_property($Panel, "position:x", 0.0, 0.3)
await tween.finished
$Panel/CloseButton.grab_focus() # runs after tween endsCommon Tween Recipes
Copy-paste patterns for everyday game polish.
func update_health_bar(new_hp: int, max_hp: int) -> void:
var tween := create_tween()
var target_value := float(new_hp) / float(max_hp) * 100.0
tween.tween_property($HealthBar, "value", target_value, 0.3) \
.set_ease(Tween.EASE_OUT).set_trans(Tween.TRANS_CUBIC)func show_panel() -> void:
$Panel.position.x = -400 # start off-screen
$Panel.visible = true
var tween := create_tween()
tween.tween_property($Panel, "position:x", 0.0, 0.4) \
.set_ease(Tween.EASE_OUT).set_trans(Tween.TRANS_BACK)func spawn_damage_number(amount: int, pos: Vector2) -> void:
var label := Label.new()
label.text = str(amount)
label.position = pos
add_child(label)
var tween := create_tween()
tween.set_parallel(true)
tween.tween_property(label, "position:y", pos.y - 50, 0.6)
tween.tween_property(label, "modulate:a", 0.0, 0.6) \
.set_ease(Tween.EASE_IN)
tween.chain().tween_callback(label.queue_free)func screen_shake(intensity: float, duration: float) -> void:
var camera := get_viewport().get_camera_2d()
var tween := create_tween()
tween.set_loops(int(duration / 0.05))
tween.tween_property(camera, "offset",
Vector2(randf_range(-1, 1), randf_range(-1, 1)) * intensity, 0.05)
tween.tween_callback(func(): camera.offset = Vector2.ZERO)Common Tween Pitfalls
Quick fixes for the most frequent tween bugs in Godot 4.
# BUG: Godot 4 removed the Tween node
# var tween = Tween.new() # ERROR
# FIX: use create_tween()
var tween := create_tween()# BUG: creating new tween each frame without killing old one
func _process(delta: float) -> void:
var tween := create_tween() # NEW tween every frame!
tween.tween_property(self, "position", target, 0.5)
# FIX: track and kill previous tween
var move_tween: Tween
func move_to(target: Vector2) -> void:
if move_tween and move_tween.is_running():
move_tween.kill()
move_tween = create_tween()
move_tween.tween_property(self, "position", target, 0.5)# Tweens from create_tween() die when the node leaves the tree
# FIX: use get_tree().create_tween() for scene transition effects
func fade_to_black() -> void:
var tween := get_tree().create_tween() # survives node removal
tween.tween_property($Overlay, "modulate:a", 1.0, 0.5)
await tween.finished
get_tree().change_scene_to_file("res://scenes/next_level.tscn")Node-bound tweens are auto-killed when the node exits tree. Use get_tree().create_tween() for global effects.
Can you write this from memory?
Set up a tween animation system for smooth effects, storing it in a variable called tween.