Skip to main content

Background Loading in Godot | DICODE

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

Popular posts from this blog

Complete 2D player movement, Beginner to Pro in Godot

 Have you ever wondered why these games feel so good to play? If your answer is visuals then ,  No the key component is their controls. The character movement feels natural, and they move exactly how you want. A good character movement will always make the player feel that they are in total control of the character.  So, you are wondering how to achieve this?  Well, there are some tricks that professional developers use to make their control better. And today we are goanna see what they are and how you can do it in Godot. VIDEO TUTORIAL COMPLETE CODE: extends KinematicBody2D var velocity : Vector2 export var max_speed : int = 1000 export var gravity : float = 55 export var jump_force : int = 1600 export var acceleration : int = 50 export var jump_buffer_time : int = 15 export var cayote_time : int = 15 var jump_buffer_counter : int = 0 var cayote_counter : int = 0 func _physics_process(_delta): if is_on_floor(): cayote_counter = cayote_time if not is_on_floor(): if cayot

Improve your jumping! | Type of jumps in Godot

Wall jump, Wall climbing, Wall sliding and double jump are some of the most common mechanics for a plat-former game. And on top of that they are super easy to create in Godot. So in this Godot tutorial, I have tried to implement all these things in the simplest way possible. I would highly recommend you to watch the 2-D movement video first, because I am adding wall jumps and other stuff in that same script. So, watch it at 1.5x speed! to get an overview. VIDEO TUTORIAL TEXT TUTORIAL Double Jump For this, create a variable jump_counter. This will keep track of how many jumps we have done, while we're in the air. So by default it will be 0. var jump_counter : int = 0 <------- var jump_buffer_counter : int = 0 var cayote_counter : int = 0 Now if you remember, in the previous video, when we are pressing the jump button. We are setting the jump_buffer_counter. So, when we are not on the ground, we will check if buffer_counter > 0 This will be true, only when we have pressed th