Since the load function doesn’t have an instantiate method in Godot 4.5, the following solution worked for me. Am I correct in understanding that the free() function doesn’t free the entire sub-scene, but only its root node, and that I’m simply adding the object to the current window?
extends Node
# Called when the node enters the scene tree for the first time.
func _ready() → void:
pass # Replace with function body.
#var scene01 = get_tree().change_scene_to_file("res://node_3d.tscn")
var scene01 = load("res://node_3d.tscn")
var pasce = PackedScene.new()
pasce.pack($Node3Dscene01)
#pasce.pack(scene01.get_node)
#var tscene = SceneTree.new()
var dfdsfsd = get_node($Node3Dscene01.get_path())
var dfgmkfmfdl = dfdsfsd.get_parent()
print(dfdsfsd.get_parent())
print(dfdsfsd.get_index())
#$Node3D.hide()
$Node3Dscene01.free()
print(dfdsfsd)
#pasce.cancel_free()
#scene01.cancel_free()
pasce.instantiate()
#get_tree().change_scene_to_packed(scene01)
#get_tree().change_scene_to_packed(pasce)
#get_tree().change_scene_to_file("res://main.tscn")
#var scene01 = preload("res://node_3d.gd")
Or point me to a ready piece of code on how to programmatically load a scene into the current SceneTree and display it without using get_tree().change_scene_to_path.
const TEST = preload("res://test.tscn")
func _ready() -> void:
var test = TEST.instantiate()
get_tree().root.add_child.call_deferred(test)
The “call_deferred” part might not be needed, depends on when you are setting this up. I had to add it, because I did it in the Autoload.
PS: Your piece of code is super confusing and I have no idea what purpose it serves. But if you just want to load a scene into the SceneTree, then here you go.
var level_path: String #actual file path that is passed in via signal
var current_level: Node
#This function doesn't exist in my code. There it's in another state.
func load_level() -> void
ResourceLoader.load_threaded_request(level_path)
func _process(delta: float) -> void:
var status = ResourceLoader.load_threaded_get_status(level_path)
if status == ResourceLoader.THREAD_LOAD_LOADED:
set_process(false)
await get_tree().create_timer(0.5).timeout
_start_level()
func _start_level() -> void:
var scene = ResourceLoader.load_threaded_get(level_path)
var new_level = scene.instantiate()
add_child(new_level)
if new_level != current_level and current_level != null:
current_level.queue_free()
current_level = new_level
If you want to see the full code check out my Game Template. It handles a lot of pesky things like that for me. Basically, in Game I define the starting level, and from then on the level the character is in is just saved where ever they go. It also pops up a loading bar every time a level is loaded. There are examples (and instructions) for 2D and 3D games and it’s a plugin so you can play with it. It’s open source so feel free to borrow what works and leave the rest. I am actively updating it every week or so.
extends Node
var scene_path = "res://node_3_dscene_01.tscn"
var packed_scene : PackedScene
# Called when the node enters the scene tree for the first time.
func _ready() -> void:
pass # Replace with function body.
packed_scene = load(scene_path)
var scene_instance = packed_scene.instantiate()
$".".add_child(scene_instance)
print($".".get_children()[1])
var test_child = $".".get_child(1)
#test_child.free()
scene_path = "res://node_3_dscene_02.tscn"
packed_scene = load(scene_path)
scene_instance = packed_scene.instantiate()
$".".add_child(scene_instance)
# Called every frame. 'delta' is the elapsed time since the previous frame.
func _process(delta: float) -> void:
pass
“Yes, that’s exactly what I needed. This is just a test version of the code for now. I really liked your state machine plugin, and I’ll take more time to understand it better later.”
I just didn’t understand why Godot doesn’t have method return a node from the add_child() function, and whether the game might behave unpredictably when using get_child() if there are many instances
What would you expect it to return? To add a node, you have to have a reference to the node you’re adding, and you’re running the function on the node that it’s being added to.
That function requires an index and retrieves the nodes in order starting at 0. If you want a specific node, use a loop.
var label: Label
for node in get_children():
if node is Label:
label = node
break