Changing sub scene(part of scene) not whole scene

:information_source: Attention Topic was automatically imported from the old Question2Answer platform.
:bust_in_silhouette: Asked By VincePrinceKing
:warning: Old Version Published before Godot 3 was released.

enter image description here

If i have the following Main scene. “Viewport” gets filled with the player, the maps with npcs and tilemaps and so on.
The “CanvasLayer” gets filled with Gui Elements, like menu-elements or health-bars.
Viewport and CanvasLayer are both Childs of the MainScene which is the first scene to get loaded.

My question now, how can i delete the scenes under Viewport and then load new ones under there (If i want to change the map for example), without changing the rest.
With the following code, located in a singleton, i can change the whole scene, how would have i to change it to just change sub scenes?

func _ready():
currentScene = get_tree().get_root().get_child(get_tree().get_root().get_child_count() -1)

.

func change_scene():
#clean up the current scene
currentScene.queue_free()
#load the file passed in as the param "scene
var s = ResourceLoader.load(scene)
#create an instance of our scene
currentScene = s.instance()
# add scene to root
get_tree().get_root().add_child(currentScene)
:bust_in_silhouette: Reply From: Zylann

I do something similar in my game:

func change_level(next_level_path):
	
	var level_container = get_tree().get_root().get_node("Main/Viewport")
	
	# Clear everything under Viewport
	for i in range(level_container.get_child_count()):
		var child = level_container.get_child(i)
		child.queue_free()

	# Load level under viewport
	var next_level_res = load(next_level_path)
	var next_level = next_level_res.instance()
	level_container.add_child(next_level)


# Usage:
change_level("res://your/level.tscn")

Why do you call get_node() on the root node of the scene tree? The change_level()-function will reside in a node that is part of the same scene as “Main/Viewport”, right?

By accessing the tree’s root node you add an unnecessary requirement, namely that “/Main/Viewport” is a valid path. As soon as you decide to instantiate this scene in some other scene it’s not going to work anymore.

Warlaan | 2016-11-07 17:28

I am assuming the function will be in a singleton as said in the question, that’s why I use get_tree(). Also get_root() doesn’t returns the actual root node of the scene, so I have to use get_node().

"/Main/Viewport" is shorter to write indeed. I got used to the explicit form.

This technique is a nice alternative to singletons (I saw that in Minilens too), and scenes instanced like this can work if you design them properly (so they won’t try to fetch their parent using a path).

Zylann | 2016-11-07 18:44