Coding Quests
The Scroll Library
Tutorials

Godot 4 Scene Transitions: Fade Between Scenes

June 16, 20265 min read

A hard cut between scenes feels cheap. The screen just blinks and you're somewhere else. A half-second fade to black and back makes the same scene change feel deliberate and polished. It's one of those tiny touches that quietly signals "this was made with care." Here's how to build a transition you can call from anywhere.

The plan

You want one transition system the whole game shares, not a copy pasted into every scene. So we'll build an autoload: a persistent script that owns a black overlay, fades it in, swaps the scene while the screen is black, then fades it back out. One function call and the whole dance happens.

Build the overlay

Make a new scene with this structure:

  • CanvasLayer (root) so the overlay always draws on top of everything
    • ColorRect named Fade, color set to solid black, anchored to fill the full screen

Set the ColorRect's alpha to 0 to start, so it's invisible. Save the scene as scene_transition.tscn.

The transition script

Attach this script to the CanvasLayer root:

GDScript
extends CanvasLayer
@onready var fade: ColorRect = $Fade
func _ready() -> void:
# Keep running even if the game is paused
process_mode = Node.PROCESS_MODE_ALWAYS
# Start fully transparent and let clicks pass through
fade.modulate.a = 0.0
fade.mouse_filter = Control.MOUSE_FILTER_IGNORE
func change_scene(path: String, duration: float = 0.3) -> void:
# Fade to black
fade.mouse_filter = Control.MOUSE_FILTER_STOP
var tween := create_tween()
tween.tween_property(fade, "modulate:a", 1.0, duration)
await tween.finished
# Swap the scene while the screen is black
get_tree().change_scene_to_file(path)
# Fade back in
tween = create_tween()
tween.tween_property(fade, "modulate:a", 0.0, duration)
await tween.finished
fade.mouse_filter = Control.MOUSE_FILTER_IGNORE

Add this scene as an autoload named SceneTransition in Project Settings.

Use it from anywhere

Now changing scenes with a fade is one line, from any script in the game:

GDScript
func _on_play_pressed() -> void:
SceneTransition.change_scene("res://scenes/Level.tscn")

The overlay fades up, the scene swaps behind the black, and it fades back to reveal the new scene. That await on the tween's finished signal is what lets the steps wait for each other, and it comes straight from how tweens and signals work together.

A couple of details that matter

process_mode = PROCESS_MODE_ALWAYS is important. If you trigger a transition from a pause menu while the game is paused, the fade still needs to run, and this lets it. The mouse_filter toggling stops players from clicking buttons through the black during the fade, then lets input through again once it's clear.

Want a fancier wipe instead of a plain fade? Swap the ColorRect for a TextureRect with a shader, or animate a different property. The structure stays the same. The autoload owns it, you call one function, the transition just happens.

Tie it together

Scene transitions are the glue between your menus, levels, and game-over screens. Once this autoload exists, every scene change in your game can use it for free, and the whole thing feels a notch more finished. If you're still building out the scenes it connects, the free Inventory System quest gives you real systems and screens to wire transitions between.

FAQ

How do I fade between scenes in Godot 4?

Build an autoload with a CanvasLayer and a full-screen black ColorRect, tween its alpha to 1 to fade out, call change_scene_to_file() while the screen is black, then tween the alpha back to 0. Awaiting each tween's finished signal sequences the steps.

Why should the scene transition be an autoload?

So the whole game shares one transition instead of duplicating it in every scene. An autoload persists across scene changes, which means the overlay can keep fading in even as the scene behind it swaps, and you can trigger it from a single function call anywhere.

How do I keep a transition working while the game is paused?

Set the transition node's process_mode to PROCESS_MODE_ALWAYS. Otherwise a transition triggered from a pause menu won't animate, because the node is paused along with the rest of the game. Always is the mode that keeps it running regardless of pause state.

godottutorialuiscene-transition

Reading is the map. The quest is the territory.

Build this for real in the Inventory System Quest. It's free, no card needed.

Start the Quest
Written by Coding Quests

We teach Godot 4 by making you build complete systems: inventories, save systems, souls-like controllers, enemy AI. The scrolls are free. The quests are where it sticks.