Video Tutorial
See complete explanation in last
Full Code
extends Node
onready var loading_scene = preload("res://load.tscn")
func load_scene(current_scene, next_scene):
# add loading scene to the root
var loading_scene_instance = loading_scene.instance()
get_tree().get_root().call_deferred("add_child",loading_scene_instance)
# find the targeted scene
var loader = ResourceLoader.load_interactive(next_scene)
#check for errors
if loader == null:
# handle your error
print("error occured while getting the scene")
return
current_scene.queue_free()
# creating a little delay, that lets the loading screen to appear.
yield(get_tree().create_timer(0.5),"timeout")
# loading the next_scene using poll() function
# since poll() function loads data in chunks thus we need to put that in loop
while true:
var error = loader.poll()
# when we get a chunk of data
if error == OK:
# update the progress bar according to amount of data loaded
var progress_bar = loading_scene_instance.get_node("ProgressBar")
progress_bar.value = float(loader.get_stage())/loader.get_stage_count() * 100
# when all the data have been loaded
elif error == ERR_FILE_EOF:
# creating scene instance from loaded data
var scene = loader.get_resource().instance()
# adding scene to the root
get_tree().get_root().call_deferred("add_child",scene)
# removing loading scene
loading_scene_instance.queue_free()
return
else:
# handle your error
print('error occurred while loading chunks of data')
return
Explanation
Does your game look like it stopped working or frozen when you switch between levels. Well, this happens with me as well, but I have a lifesaving technique to cover my mess
Which is showing something to the user while your CPU works as hell. In other words, a Loading Screen. So, today we are goanna see how we can create a Loading Screen So that you can cover up your mess too.
Now, before jumping in Godot, let’s understand how it is going to work. So, as you know we have a root of the tree. Then you have your main scene that will be the entry point of your game. Now beside it, we have one script which will be in autoload So it will also come under the root.
Now other than this we have one loading scene, which you want to display when background loading will occur. And a second scene that you want to load. Now, when your game starts, first your main scene is loaded. Let’s say it is a main menu and the player clicks on the play button. Then it will send signal to autoload script and then, the autoload script will first add the loading scene to the root
After that it will delete the current scene from the root and while the loading scene is showing on the screen, it will load the next scene in parallel so that your game doesn’t look like is freezes. It can also give you the amount of data which has been loaded which you can show using the progress bar in the loading screen. Now when the all the data have been loaded, we will add the scene to the root and at last remove the loading scene.
Now all this seems way too easy because first, it actually is easy and second, the real thing hasn't started yet, so get ready!
Now for actually loading the scene we take the help of 3 functions.
First, we have ResourceLoader.load_interactive(path) which takes the path of the scene. This just returns the basic details of the scene which we will then use to actually load the data.
Secondly, we have loader.poll() this is where actually data loading starts. This will load data in small pieces. This function returns OK when it successfully loads a chunk. It returns ERR_FILE_EOF when it has loaded all the chunks and there is nothing more. And if there is some problem it will return an error.
Now third we have loader.get_stage() and loader.get_stage_count(). get_stage_count() will give the total number of pieces and get_stage() will give how many pieces we have loaded successfully.
Now you have the all the necessary details, So, let’s open to GODOT and create the loading script
First, we will extend a Node otherwise some basic functions like get_tree() or queue_free() will not work. Then we create a new function that will take the current scene and the next scene that we want to load.
extends Node
Now as I told before, the first thing we need to do is add the loading scene to the root. So, in the top we will preload the loading scene. And inside the function we will create an instance of it and then add this instance as the child of the root node.
onready var loading_scene = preload("res://load.tscn")
func load_scene(current_scene, next_scene):
# add loading scene to the root
var loading_scene_instance = loading_scene.instance()
get_tree().get_root().call_deferred("add_child",loading_scene_instance)
Once the loading scene is added then, we use the load_interactive() function to get the metadata of the scene. Now if there is some problem while finding the data. We will get NULL. So, we do a check, if we get null then we will show the error message and exit the function.
# find the targeted scene
var loader = ResourceLoader.load_interactive(next_scene)
#check for errors
if loader == null:
# handle your error
print("error occured while getting the scene")
return
Now if everything works fine then, we first delete the current scene from the root. And wait for 0.5s so that our loading scene can appear.
current_scene.queue_free()
# creating a little delay, that lets the loading screen to appear. yield(get_tree().create_timer(0.5),"timeout")
Now since the poll() function load the data in chunks. That's why we need to put that in a loop So, create an infinite loop and call the loader.poll() function and store the returned value in a variable.
# loading the next_scene using poll() function
# since poll() function loads data in chunks thus we need to put that in loop
while true:
var error = loader.poll()
Now if this function returned OK This means a chunk of data has been loaded correctly. So now we will update the progress bar here.We first get the progress bar node in the loading screen. Then we use get_stage() and get_stage_count() function to get the percentage loaded. The get_stage() will give how many pieces have been loaded till now. And get_stage_count() will give the total number of chunks available. And we are converting the numerator to float so that the resultant will be a float value.
# when we get a chunk of data
if error == OK:
# update the progress bar according to amount of data loaded
var progress_bar = loading_scene_instance.get_node("ProgressBar") progress_bar.value = float(loader.get_stage())/loader.get_stage_count() * 100
Now if this function returned ERR_FILE_EOF then means we have successfully loaded all the data. So, here we get the scene that we loaded and create the instance of it. After creating it we will add this scene as a child of the root and then we will remove the loading scene from the root and then get out of the loop.
# When all the data have been loaded
elif error == ERR_FILE_EOF:
# Creating scene instance from loaded data
var scene = loader.get_resource().instance()
# Adding scene to the root
get_tree().get_root().call_deferred("add_child",scene)
# Removing loading scene
loading_scene_instance.queue_free()
return
Now if we get something other than OK or ERR_FILE_EOF then this means there is some error while loading the pieces. So here you can write the code to handle the error and end the loop.
else:
# handle your error
print('error occurred while loading chunks of data')
return
And that’s it. You can now use this script to get load the scene.
To use this, you just need to call this function and pass "self" for current scene and path of the scene to load for the next scene
For example:
global.load_scene(self, "res://scene2.tscn)
Comments
Post a Comment