Syntax Cache
BlogMethodFeaturesHow It WorksBuild a Game
  1. Home
  2. Cheat Sheets
  3. GDScript
  4. GDScript Tweens Cheat Sheet
GDScriptCheat Sheet

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.

On this page
  1. 1Creating Tweens
  2. 2tween_property()
  3. 3tween_callback() and tween_interval()
  4. 4Sequential vs Parallel Tweens
  5. 5Easing and Transitions
  6. 6Looping Tweens
  7. 7Tween Control
  8. 8Common Tween Recipes
  9. 9Common Tween Pitfalls
Creating Tweenstween_property()tween_callback() and tween_interval()Sequential vs Parallel TweensEasing and TransitionsLooping TweensTween ControlCommon Tween RecipesCommon Tween Pitfalls

Creating Tweens

In Godot 4, create tweens with create_tween(). The old Tween node is removed — do not use Tween.new().

Basic tween creation
var tween := create_tween()
# tween is bound to this node — auto-killed when node exits tree
Scene tree tween (not bound to a node)
var tween := get_tree().create_tween()
# This tween survives node removal — use for scene transitions
Replace previous tween
var 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.

Fade out a sprite
var tween := create_tween()
tween.tween_property($Sprite2D, "modulate:a", 0.0, 0.5)
# Fades alpha from current to 0 over 0.5 seconds
Move a node to a position
var tween := create_tween()
tween.tween_property(self, "position", Vector2(500, 300), 1.0)
Scale up for a pickup effect
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)
Animate from a specific start value
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.

tween_callback() — run code at a point
var tween := create_tween()
tween.tween_property(self, "position:y", -50.0, 0.3)
tween.tween_callback(queue_free)  # remove after animation
tween_interval() — add a pause
var 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)
Callback with arguments (use bind)
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.

Sequential (default)
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)
Parallel — all at once
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)
Mix sequential and parallel
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.

Common easing presets
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)
Transition types
# 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)
Set default for entire tween
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.

Infinite hover animation
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()
Flash 3 times then stop
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)
Pulse scale loop
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.

kill() and is_running()
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 default
pause() and play()
var 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()
Await tween completion
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 ends

Common Tween Recipes

Copy-paste patterns for everyday game polish.

Health bar smooth update
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)
UI panel slide in from off-screen
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)
Damage number popup
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)
Screen shake
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.

Tween.new() does not work
# BUG: Godot 4 removed the Tween node
# var tween = Tween.new()  # ERROR

# FIX: use create_tween()
var tween := create_tween()
Stacking tweens on same property
# 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)
Tween killed when node exits tree
# 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.

Learn GDScript in Depth
GDScript Timers & Signals Practice →GDScript Movement Practice →
Warm-up1 / 2

Can you write this from memory?

Set up a tween animation system for smooth effects, storing it in a variable called tween.

See Also
Vectors →Node Operations →

Start Practicing GDScript

Free daily exercises with spaced repetition. No credit card required.

← Back to GDScript Syntax Practice
Syntax Cache

Build syntax muscle memory with spaced repetition.

Product

  • Pricing
  • Our Method
  • Daily Practice
  • Design Patterns
  • Interview Prep

Resources

  • Blog
  • Compare
  • Cheat Sheets
  • Vibe Coding
  • Muscle Memory

Languages

  • Python
  • JavaScript
  • TypeScript
  • Rust
  • SQL
  • GDScript

Legal

  • Terms
  • Privacy
  • Contact

© 2026 Syntax Cache

Cancel anytime in 2 clicks. Keep access until the end of your billing period.

No refunds for partial billing periods.