Nodes of a scene "stick" after changing scenes

Godot 4.4

I am working on a project where a scene will change after the user inputs a word. A scene is coded into a scroll container that changes when a word is entered. However, when the scene has more than one node, the extra node will stay behind when the scene changes.

Here is the code I am using to call the new scene:

extends ScrollContainer

const HAND = preload("res://scenes/hand_scene.tscn")
const FACE = preload("res://scenes/face_scene.tscn")

func _on_input_text_submitted(new_text: String) -> void:
	if new_text == "hand":
		print("hand loaded")
		var hand_scene = HAND.instantiate()
		add_child(hand_scene)
	if new_text == "face":
		print("face loaded")
		var face_scene = FACE.instantiate()
		add_child(face_scene)

Here is what the main node tree looks like:

The “hand” scene is just a TextureRect parented to a VBoxContainer. The “face” scene is two TextureRects parented to a VBoxContainer.

Here is the “face” scene, which looks as intended:

Here is the “hand” scene, which has the white TextureRect left over from the “face” scene. This only pops up when the “face” scene is called first.

Is there a way to keep the scenes fully separate?

Keep a reference to the node / scene you added in either a dictionary or an array, then when a new scene is being loaded, simply remove the previous one.

Or even easier, introduce a variable called current_scene and make it equal to the instantiated scene. Then, before you instantiate a new scene, simply check if current_scene is not null, and if it’s not, do: current_scene.queue_free() because right now you’re essentially just adding new nodes on top of each other without ever removing the old ones.

This is the code I replaced it with:

extends ScrollContainer

var current_scene

const HAND = preload("res://scenes/hand_scene.tscn")
const FACE = preload("res://scenes/face_scene.tscn")


func _on_input_text_submitted(new_text: String) -> void:
	if new_text == "hand":
		print("hand loaded")
		if current_scene != null:
			current_scene.queue_free()
		var current_scene = HAND.instantiate()
		add_child(current_scene)
	if new_text == "face":
		print("face loaded")
		if current_scene != null:
			current_scene.queue_free()
		var current_scene = FACE.instantiate()
		add_child(current_scene)

I still have the same issue, am I formatting it incorrectly?

You need to remove the var from where you SET the current_scene, otherwise you’re just creating a new variable. it should just say current_scene = FACE.instantiate() for example.

That worked for me. Thank you!

1 Like

This topic was automatically closed 30 days after the last reply. New replies are no longer allowed.