Scenes are the building blocks of game development with Godot Engine. They can be simple props, whole levels, or even the entire game world. It’s common to have each level or screen saved as an individual PackedScene and use the SceneTree.change_to
method to transition between them. Here’s a quick tip to prevent breaking immersion when transitioning between scenes: make transitions!
The idea is to locate a PackedScene in the project and perform a smooth fading transition. To make transitions, we need to cover the whole screen and animate the transparency to create a fade effect. We can use a ColorRect node for this. The ColorRect should also fade in only when the new scene is ready to prevent the new scene from displaying too soon.
Fading Animation
Create a new scene and add a ColorRect as the root. Rename it as SceneTransitionRect. On the Layout menu, select the “Full Rect” option.
This layout ensures the SceneTransitionRect covers the whole screen. You can change the Color property to any color you like, but for fading purposes, Black goes well.
For the fade animation, add an AnimationPlayer as a child of the SceneTransitionRect and create a new animation. Let’s name it Fade and set its duration to 0.5
. Since the SceneTransitionRect fades in and out, it takes twice as long, so the total duration is 1.0
second.
In this animation, the SceneTransitionRect starts completely transparent, then becomes opaque at the end. Set the alpha value of the Modulate property’s color to 0.0
and add a keyframe. Move the animation’s cursor to the end at 0.5
seconds and set the SceneTransitionRect > Modulate alpha back to 255
and add a new keyframe.
Fixing mouse click issues
If your game doesn’t have mouse events, you can skip this section. Otherwise, we need to stop the SceneTransitionRect consuming mouse events. Since it covers the screen and is on top of every other node in the scene hierarchy, it consumes mouse inputs by default.
In the SceneTransitionRect > Mouse category, change the Filter property to “Ignore” to fix this issue. Now let’s move on to the actual transition.
Transition
It’s time to code! Attach a new script to the SceneTransitionRect. Export a String variable with hints to allow us to browse the file system and search for PackedScene files. We also set up a reference for the AnimationPlayer.
extends ColorRect
# Path to the next scene to transition to
export(String, FILE, "*.tscn") var next_scene_path
# Reference to the _AnimationPlayer_ node
onready var _anim_player := $AnimationPlayer
Since we want the SceneTransitionRect to fade in when it’s ready, we can perform the Fade animation in the _ready()
callback and play it backward to start opaque then become transparent.
func _ready() -> void:
# Plays the animation backward to fade in
_anim_player.play_backwards("Fade")
Now it’s time to code the actual transition. We want the SceneTransitionRect to fade out completely and load the next scene. By default, it should transition to the next_scene_path
, but we can also pass a different PackedScene path as an argument.
func transition_to(_next_scene := next_scene_path) -> void:
# Plays the Fade animation and wait until it finishes
_anim_player.play("Fade")
yield(_anim_player, "animation_finished")
# Changes the scene
get_tree().change_scene(_next_scene)
Using the SceneTransitionRect
There are many use cases for this node. Let’s say you have a main menu with three buttons that load different scenes:
- Start
- Options
- Credits
You can attach a script to the topmost node and connect each button pressed
signal to a callback:
onready var _transition_rect := $SceneTransitionRect
func _on_StartButton_pressed() -> void:
_transition_rect.transition_to("res://path/to/Play.tscn")
func _on_OptionsButton_pressed() -> void:
_transition_rect.transition_to("res://path/to/Options.tscn")
func _on_CreditsButton_pressed() -> void:
_transition_rect.transition_to("res://path/to/Credits.tscn")
Demo scene
In our project demo scene, we used a SceneButton. It’s a simple button that also exports a variable so we can browse to a PackedScene path in the file system. It has a custom signal called scene_prompted
. This is connected to the SceneTransitionRect.transition_to()
method. When the Scenebutton is pressed, it passes the scene_path
to the SceneTransitionRect.transition_to()
method so the transition can start.
Made by
Our tutorials are the result of careful teamwork to ensure we produce high quality content. The following team members worked on this one:
Tutor
Tutor