add_child does not work

Godot Version

v4.5.1.stable.arch_linux

Question

My project starts from menu scene

menu.gd

extends Control

func _ready() -> void:
	pass # Replace with function body.

func _process(delta: float) -> void:
	pass

func _on_planet_pressed() -> void:
	get_tree().change_scene_to_file('res://scenes/game.tscn')

In game.gd I call add_child function

extends Node2D

func _ready() -> void:
	var scene := preload('res://scenes/flying_islands/classic/elevator.tscn')
	$Level.add_child(scene.instantiate())
	var all_descendants: Array = $Level.find_children("*", "", true)
	for node in all_descendants:
		print(node.name) # no logs

func _process(delta: float) -> void:
	pass

But it does not work. After starting game and clicking the button in menu game scene loads with gray screen, music and squirrel sprite. Here are game’s nodes

Elevator’s nodes

If I press f6 in Elevator scene it works(without music and killzone). Also if I copy Elevator’s nodes to game’s Level node via godot’s interface everything works.

How can I add Elevator’s node to Game node via godot script?

Here is my project in zip https://drive.google.com/file/d/1aKQmuhC1WZ309AG2oldqkkx-3XKJmuP8/view?usp=drive_link

Do you have any errors or warnings in the Editor?

This line might be the issue:

Try changing it to:

	$Level.add_child.call_deferred(scene.instantiate())

Only sometimes when open godot
ERROR: Required extension VK_KHR_surface not found.
ERROR: drivers/vulkan/rendering_context_driver_vulkan.cpp:928 - Condition “err != OK” is true. Returning: err

During debugging my game no errors or any logs in console.

$Level.add_child.call_deferred(scene.instantiate()) does not help

  • Instead of trying to find your node manually, open the “Remote” scene tree while running your game and check if your node shows up in the tree.
  • Change your “Level” node to a Node2D. Technically not necessary but it prevent problems in the future.
  • Are you really sure that _ready() in game.gd gets called?
1 Like
  1. Strange. In Remote I can see only Elevator(root) and one island were added. TextureRect, TileMapLayer, FlyingDutchman, IslandSmall2. IslandSmall3 were not added. In fact, I can’t see this island on the screen. Only squirrel and gray screen

  2. Ok

  3. If I add logs START and FINISH they print immediately after entering the game scene

func _ready() -> void:
	print('START')
	var scene := preload('res://scenes/flying_islands/classic/elevator.tscn')
	$Level.add_child(scene.instantiate()) # or $Level.add_child.call_deferred(scene.instantiate())
	var all_descendants: Array = $Level.find_children("*", "", true)
	for node in all_descendants:
		print(node.name)
	print('FINISH')

But still no logs for node in all_descendants: print(node.name), only START and FINISH

Are you sure you’re loading the correct file?

1 Like

Now I noticed that I have two elevator.tscn files: res://scenes/flying_islands/classic/elevator.tscn and res://scenes/elevator.tscn. Thank you all

1 Like

You add Elevator’s node to Game node successfully, but the find_children() method is being used incorrectly.

Try this:

$Level.find_children("*", "", false, false)

That’s why it’s best to work with uid:// instead.

It makes the code more cryptic though.

Yes, unfortunately. But I’d rather deal with that problem and for example assign these resources to meaningfully named variables. But there is hope that we will deal with this issue in the future with better tools, like hints in the editor.