Skip to content

Background Loading

Manolo Cantón edited this page Jul 20, 2024 · 7 revisions

I saw the possibility of loading a PackedScene in the background using ResourceLoader.load_threaded_request, so I wanted to take advantage of this in case you work with very large scenes (at least I haven't gotten to something like that yet). But I've seen people wanting this, so I've tried to add it, as well as putting in a custom loading screen.

That said, it only makes sense for the method SceneManager.change_scene_to_file, which has the optional param called min_duration. It indicates the minimum loading scene time. I think this is reasonable because it makes no sense to see the loading screen as a flash. Example:

SceneManager.change_scene_to_file("my_scene.tscn", {}, 0.5, {
    loading_screen_property = "a value"
})

In this case, the loading screen has a minimum time of 0.5 seconds. If the PackedScene takes longer, it will last longer, but if it is loaded earlier, it will wait until this time has elapsed.

You can also observe a fourth param. It works the same as the second properties param but this is passed to the loading screen.

With the setting addons/scene_manager/loading_screen/print_loading_times enabled, it prints scene loading times. This allows to see if it is really necessary to use a background loading for the scene. Also it prints appended resources times.

Loading Screens

You can extend LoadingScreen to create your amazing loading screen. You must override methods to change the behavior:

  • _get_range_object Returns a object with value property, which indicates the loading progress. value must be a float and takes values between 0.0 and 100.0.
  • _get_tween_duration Time it takes to reach the new value.
  • handle_load_error This is called when scene cannot be loaded. You can use it to show an error on loading screen.
extends LoadingScreen

func _get_range_object() -> Object:
    return get_node("MyRangeNode")

func _get_tween_duration() -> float:
    return 0.1

func handle_load_error() -> void:
    get_node("MyErrorLabel").text = "Scene cannot load..."

You can use your custom one by calling the SceneManager.set_loading_screen() method which has a type param to indicate how to use this loading screen:

  • LoadingScreen.Type.DEFAULT. Replaces the default loading screen and uses it on next loads.
  • LoadingScreen.Type.PERSIST. Uses it on next loads until other loading screen is set. You also can use SceneManager.reset_loading_screen() to set the default loading screen.
  • LoadingScreen.Type.ONE_SHOT. Uses it on one load. After setting the default loading screen.

So you can use SceneManager.set_loading_screen() in your main scene to set a default loading screen or the most efficient would be to change the value of the project setting addons/scene_manager/loading_screen/default_scene_path. When SceneManager is ready, it has loaded the packed scene from the setting value.

Appending Resources

You can load extra resources to pass to next scene properties. You must use SceneManagerResourceRef which returns the SceneManager.append_resource method in your properties dictionary values. All these classes are parsed with the resources that are loaded in the background. It supports this in Array and Dictionary values too, but it doesn't work with object properties. Since it checks all arrays and dictionaries (supporting cyclic references which are checked once) it is advisable not to include large amounts of values in the properties parameter.

SceneManager.change_scene_to_file("my_scene.tscn", {
    characters = [
        SceneManager.append_resource("my_character1.tres"),
        SceneManager.append_resource("my_character2.tres"),
    ],
}, 1.0)

When the next scene is in the scene tree, parse ref with the resource and set the characters property. You can use SceneManager.reset_options() to remove options which includes to remove appended resources.

Clone this wiki locally