Hello, For my game, I am programatically creating instances of a node called Pet. I also have an Area2d with a collider name Ground in my main scene. I want to detect when the Pet node reaches the Ground with the Ground's signal body_entered. However, I cannot connect the signal to the Pet script since it is not in my main scene where the Ground is. Only instances of Pet is added in the main scene at runtime.

Is there another way to connect the signal to the Pet script? I tried adding these lines to my Pet script in _on_ready() but the ground_node is null:

var ground_node = get_tree().get_root().find_node("Ground")
ground_node.connect("body_entered", self, "_on_Ground_body_entered")

Thank you in advance!

Not totally sure how viable this would be, but you could try adding the ground to a group using add_to_group("ground") and then you could use get_tree().get_nodes_in_group("ground") to get a reference to the ground. You'll probably want to use a yield for a single frame though, so all the nodes have a chance to register themselves before you try to get them. Something like this should, I think, work:

# On the ground
func _ready():
	add_to_group("ground")

# On the pet
func _ready():
	# do any initialization that does not need the ground node here
	
	# wait a single idle frame so all nodes have a chance to set themselves up
	yield(get_tree(), "idle_frame")
	var possible_ground_nodes = get_tree().get_nodes_in_group("ground")
	
	# if you want to connect to all ground nodes:
	for ground_node in possible_ground_nodes:
		ground_node.connect("body_entered", self, "_on_Ground_body_entered")
	
	# if you just want to connect to the first ground node
	# if (possible_ground_nodes.size() > 0):
		# possible_ground_nodes[0].connect("body_entered", self, "_on_Ground_body_entered")

@TwistedTwigleg , thank you! This is working for me once the pet instance has been created. I am also having a similar issue with updating my HUD when the pet is caught by the player. I tried the above approach (this time with pet being added to a group and use the connect method in the HUD script). But since the HUD's on_ready() function is called before the Pet's on_ready(), it doesn't work.

Is there a similar approach I could try?

Thank you!

One solution is to do the connect() in a node that's a common ancestor of HUD and Pet.

All nodes have a process_priorty variable in the editor which determines which one runs first, I suggest you try using that.

Does process_priority affect ready()? From the documentation, it sounds like it only affects process() and _physics_process().

@hbernal said: @TwistedTwigleg , thank you! This is working for me once the pet instance has been created. I am also having a similar issue with updating my HUD when the pet is caught by the player. I tried the above approach (this time with pet being added to a group and use the connect method in the HUD script). But since the HUD's on_ready() function is called before the Pet's on_ready(), it doesn't work.

Is there a similar approach I could try?

Thank you!

Great, I'm glad it worked! :smile:

For the HUD and pet, what you may want to do is try to connect the signals in _process and use a boolean to detect if the signal has been connected or not for faster compares (to minimize the performance impact).

Something like this (pseudo code):

var is_signals_connected = false
var signal_connection_tries = 0

func _process(delta):
	if is_signals_connected == false:
		signal_connection_tries += 1
		if (signal_connection_tries >= 10):
			print("ERROR - could not connect signals in ", name, " after 10 tries!")
		
		var nodes_in_group = get_tree().nodes_in_group("group_here")
		if (nodes_in_group.size() > 0):
			nodes_in_group[0].connect(...) # connect signal
			is_signals_connected = true

With it running in _process it should execute after all the nodes have executed in _ready, and by doing it until the signals are connected, even if there is a bit of setup needed afterwards it should still properly connect as long as the HUD/Pet is added to the correct groups in _ready, regardless of the scene order.

4 days later

Thank you for all the suggestions! Sorry for seeing this a bit late, I actually made a workaround to just get the HUD in my Pet script in the only method where I needed it. It works, but definitely not the best solution haha ' @Perodactyl and @TwistedTwigleg I'll try to see if I can implement either your solutions. It would be great to get the HUD node in the Pet script once instead of my way of getting each time one method is called.

@hbernal One simple thing I'd try is pass ground to the pet's constructor, with access to ground that way connecting the signals should be easy.

a year later