Child node not found within instanced scene

:information_source: Attention Topic was automatically imported from the old Question2Answer platform.
:bust_in_silhouette: Asked By CarapaceonBear

I’m instancing a scene, using a constructor.
Within that scene, I have a script targeting a node as normal, using onready var example = $Example.
It autofills when typing, and the child is the only thing below the root node in the hierarchy.
But when _ready() happens, the node is null.

This is a stripped-down version of the script:

extends Node2D

class_name Alien

var thisColour
var health
onready var alienSprite = $Alien_Sprite

func _init(alienColour):
	thisColour = alienColour

func _ready():
	match thisColour:
		"beige":
			alienSprite.play("beige")
			health = 20
		"green":
			alienSprite.play("green")
			health = 30
        etc.

and in the main scene, it’s being instanced with:

var newAlien = Alien.new("green")
add_child(newAlien)

calling print(alienSprite) in _ready() gives [Object:null]

In the debugger, it says “Attempt to call function ‘play’ in base ‘null instance’ on a null instance”.

The error goes as follows:
error log

:bust_in_silhouette: Reply From: godot_dev_

I am not exactly sure what the technical cause of the issue is, but I have encountered this frequently. To solve it, instead of assigning a reference of your child nodes to a variable on ready, have another function (e.g. initChildReferences) assign the reference, and call that function after adding the scene instance to the scene tree. For example:

var newAlien = Alien.new("green")
add_child(newAlien)
newAlien.initChildReferences()

and in your Alien script you would have :

func initChildReferences():
      alienSprite = $Alien_Sprite

There may be a better way, but this is the work around I have found to consistently solve such problems

Thanks for your answer, that’s a good addition to my code toolbox.

Unfortunately, in this case it isn’t working. The child node is still null, the script doesn’t seem able to find it, despite it being the only child node, and named the same as what it’s looking for. Running get_children() after initialisation is just returning an empty array.

CarapaceonBear | 2022-08-08 15:18

The only thing I can think of is a naming issue. Double check to make sure your child node is the same name you use when use the node path to get the child.

If that doesn’t work, try waiting a frame and then checking if get_children still returns an empty list. Maybe after a frame processes, the child wiill be present

godot_dev_ | 2022-08-08 17:56