Unloading/loading a scene, am i doing something wrong?

Godot Version

4.7.2-stable

Question

I am trying to load/unload child scenes (scene_instance) of my main scene.

This is the main scene’s script:

extends Node2D

# this script loads and unloads the main scenes in the game from the root node

var scene_instance = null


# Called when the node enters the scene tree for the first time.
func _ready():
	SceneSwitcher.main_scene = self
	var scene_resource := load("res://scenes/main_scenes/game.tscn")
	
	if (scene_resource):
		scene_instance = scene_resource.instantiate()
		print("Loaded scene: ", scene_instance)
	else:
		print("No main scene to load")
	pass

func unload_scene():
	if (is_instance_valid(scene_instance)):
		print("Unloading scene: ", scene_instance)
		scene_instance.queue_free()
	scene_instance = null
	
func load_scene(scene_name : String):
	unload_scene()
	var scene_path := "res://scenes/main_scenes/%s.tscn" % scene_name
	var scene_resource := load(scene_path)
	
	if (scene_resource):
		scene_instance = scene_resource.instantiate()
		self.add_child(scene_instance)
		print("Loaded scene: ", scene_instance)
	else:
		print("No scene!")

For context: the scene i load in the beginning is game.tscn.

SceneSwitcher is the name of an autoload that calls load_scene(name) when i actually want to load scenes.

The issue i am having here is that when load_scene() is called, unload_scene() doesn’t seem to work as it should. The new scene (intro) is added as a child to main_scene, but the original (game) is never removed.

I get this output:

Loaded scene: game:<Node2D#56841209621>
SceneSwitcher: attempting to load intro
Unloading scene: game:<Node2D#56841209621>
Loaded scene: Intro:<Node2D#60163098425>

This is what the remote tree looks like before the function is called:

This is after:

I have also attempted to use free() instead of queue_free() but it hasn’t made any noticeable difference

Thanks for any help!

queue_free as the name suggests will queue the instance to be removed at the end of the current tick. You are still in that same tick, hence why it’s not removed yet.

If you absolutely need it removed right away, use free. But this is not recommended.

Thanks for your response, i updated the post because this made me realize that it looked like just bad debugging. The unload_scene function still seems to not remove the instance at all, even with free()

You don’t seem to add (add_child) the initial scene anywhere, it won’t look like anything is being deleted from the scene tree because this scene_instance is not inside the scene tree, it’s ~~~floating in the void~~~

Found out that my code was barely part of the issue at all. From before, i had already added the “game”-scene to my main_scene. This means that the script did actually remove the game scene, i just didnt notice because it was layered over an identical version of itself. I also never added the game scene through the script. Removing the game scene from main_scene and adding add_child(scene_instamce) in the _ready() function solved it :wink:

Thanks! Noticed this as well just now