Trouble unloading scenes

Godot Version

4.6 stable

Question

How do I properly unload a scene?

So currently I’m working on a scene manager for my game, each time I have a scene that needs to be loaded I instantiate it by sending a signal to the scene manger script. This script will then use the scene_id to identify a specific scene and uses add_or_remove to see if the scene needs to be instantiated or unloaded. Now my problem comes in when I go to unload a script!

At first the script wouldn’t need name_scene = find_child("scene_name", true, true) for id 2-4 (its why its commented out). Being the silly billy I am I just moved on and said “if it works it works” but later on when I would unload the scene more than twice (scene id 2-4) and error would pop up saying:

Attempt to call function ‘queue_free’ in base ‘previously freed’ on a null instance.

After that I just gave up and now we’re here!!! If you have any questions to help you get more details please let me know!

func _on_scene_requested(scene_id, add_or_remove):
	if add_or_remove == "add":
		match scene_id:
			1:
				name_scene = main_menu_scene.instantiate()
				add_child(name_scene)
			2:
				name_scene = main_game_scene.instantiate()
				add_child(name_scene)
			3:
				name_scene = pull_up_menu_scene.instantiate()
				add_child(name_scene)
			4:
				name_scene = how_to_play_menu_scene.instantiate()
				add_child(name_scene)
	elif add_or_remove == "remove":
		match scene_id:
			1:
				name_scene = find_child("main_menu", true, true)
				name_scene.queue_free()
			2:
				#name_scene = find_child("main_game", true, true)
				name_scene.queue_free()
			3:
				#name_scene = find_child("pull_up_menu_scene", true, true)
				name_scene.queue_free()
			4:
				#name_scene = find_child("main_game", true, true)
				name_scene.queue_free()
	else:
		print("bruh _on_scene_changed didn't work")

TBH, this is the root of your problem. Having something called Manager is what’s known as an anti-pattern. It’s a practice that is detrimental to the functioning and maintenance of you code. When you name something “Manager” you then look for things for it to manage. The object becomes more bloated over time, as you try to stuff it with responsibility it doesn’t need. It is in fact like many middle managers in a company - useless and only there to tell people what to do and report what they’ve done.

In this particular example, you are trying to create a tool to do something that’s already being done by the Godot Engine, which is memory management. Your error message is telling you this:

99% of the objects you’re going to commonly use in Godot inherit from RefCounted. RefCounted objects deal with garbage collection. They track how many of an object exist, and when they are all gone, free them from memory.

So you are trying to manage what Godot is doing, and that’s why you’re getting an error.

Upon reading your code, it seems like you are over-optimizing. You are future-proofing your code to make sure you only have one scene loaded at a time. All four of those scenes can exist in memory without issue, and probably should so that the player doesn’t have to wait for them to load. They do not take up that much room in RAM.

It might be worth it to ask yourself what you hope to accomplish by creating this “Scene Manager”.

3 Likes

Ah I see now, thanks for the help!

1 Like