Godot Engine

Godot Engine

AD Mar 23 @ 4:56am
Can someone explain to me why I get null in _ready()???
Hi all.

I have a scene that has a timer that is a direct child node of the scenes root node. I want to start said timer or not based on an initial condition, and so I setup the Timer in the _ready() function like this:
$VisibilityCheckTimer.timeout.connect(_on_visibility_check)
$VisibilityCheckTimer.start()
Basically the timer will periodically check if an enemy can see the player or things on the players side.

The problem is, this timer is null. Why is it null? It's a child node of the root node, so shouldn't it be possible to reference it in _ready()?

If it's a good idea to use a timer for this is besides the point right now. I want to understand when I can use nodes in _ready() and when i can't (as well as why), because I keep running into issues where they are null and I don't get why. So I'm using the most recent case where it happened to me as an example.
Last edited by AD; Mar 23 @ 4:59am
< >
Showing 1-5 of 5 comments
Romløk Mar 23 @ 5:17am 
Did you by any chance add a child node to your scene, when you should've instantiated a child scene instead? I do that all the time when I have a scene which has a root node with a class_name!

Other possibilities that I've encountered:
- Typo in the node name;
- Using % when I mean $, or vice versa.
AD Mar 23 @ 6:41am 
Originally posted by Romløk:
Did you by any chance add a child node to your scene, when you should've instantiated a child scene instead? I do that all the time when I have a scene which has a root node with a class_name!

Other possibilities that I've encountered:
- Typo in the node name;
- Using % when I mean $, or vice versa.
I am not sure what the difference is between the first two things, so that might be it. It's a "SensesComponent", basically resposible for sensing things. I made it into a class_name but added it as a child node. Does that change the semantics around how this works?
Romløk Mar 23 @ 6:59am 
If you add a child node, all you get is the node. You don't get any children unless the class creates them through code. What you seem to rather want is an instance of the scene (.tscn) which includes the children.

In the editor, it's the difference between the two buttons in the top-left of the scene tree.

In code, it's the difference between `SensesNode.new()` and `preload("res://senses_component.tscn).instantiate()`
Where is the script, in relation to the node?

If the script is attached to the root node (that is the parent of the timer node), then $VisibilityCheckTimer should work. If the script is attached to another node in the tree, then you'll want something like $/root_node/VisibilityCheckTimer instead.

Alternatively, create the timer via code:
await get_tree().create_timer(delay_in_seconds).timeout

This will create a timer, start it, wait for it to time out, then continue executing the code in the function when the timer expires. The timer will automatically be removed from the tree when the function ends, due to scope.
See https://docs.godotengine.org/en/stable/tutorials/scripting/gdscript/gdscript_basics.html#awaiting-signals-or-coroutines for more details.
Last edited by umop-apisdn; Mar 23 @ 7:11am
AD Mar 23 @ 7:44am 
Originally posted by Romløk:
If you add a child node, all you get is the node. You don't get any children unless the class creates them through code. What you seem to rather want is an instance of the scene (.tscn) which includes the children.

In the editor, it's the difference between the two buttons in the top-left of the scene tree.

In code, it's the difference between `SensesNode.new()` and `preload("res://senses_component.tscn).instantiate()`
That's strange, because when I look into my code, I am doing it exactly the same in other places and there is works. I am even testing to just start the timer unconditionally by just setting autostart to true, and for some reason, it doesn't work. Setting autostart to true, connecting a method to the timeout signal to and then running does not seem to start the timer.

Don't know if it matters, but the scene is an Area3D. The idea is, if an enemy enters the area, it starts checking if it can be seen or not. Don't know why nothing is happening, though...
< >
Showing 1-5 of 5 comments
Per page: 1530 50