I have this problem where whenever I start the game the Game manager (which is going to be the game global variables and signals manager) sends a signal to hide the Area_P object which is a Area2D which contains a CollisionShape2D and a Sprite2D. It does so by when the signal is received by area_P, it will inside its own script acess the property visible of the two child nodes and try to hide them. Problem is, as stated in the title, it returns an error because the two variables I declare to reference the child nodes of Area_P are null for some reason. Is there a better way to do what Im doing and most importantly, why is this error occurring in the first place? I tried looking for other topics on this on the forum but due to my inexperience I think (at least) some of them arent related or I cant make out whats wrong in their case
I’m not sure where the script actually is, but it’s not attached to the Area2D node. There would be an icon next to it in the Scene tab indicating a script was attached if it were.
One issue you may have is that the signal is emitted on manager.gd ready, while the area_2d.gd variables are also set on ready (using the onready technique). Depending on the order of the ready calls, those variable may just not be initialized yet.
In the _on_manager_startup_hide_all() function, try to set your variables, and see if it works.
Like this:
And then you can change the nodes structure to fix the order of ready calls, or just remove the onready assignments and do it another way. To avoid setting the variables each time the signal is triggered, you can also check if they are null, like this:
On top of the answers you got already, you are breaking the unwritten rule “call down, signal up”
There isn’t really a need to emit that signal from your global manager. Your manager should have access to Area_P directly and therefore should be calling into a function area_p.hide_all().
This is going to mean a design shift but you should to do it anyway since autoloads are always loaded first. No non-global nodes will be ready in that globals _ready() function.
It seems to have solved the issue but I’m still not 100% how the problem with onready is solved, when I use a variable that is initialized with @onready, I need to do
"if variable == null:
variable = $path
to always solve it? Or theres a better way to solve this issue?
this code is mostly completely useless.
hiding a node will hide its children, and using onready already sets the references. setting references should not be done from a function connected to a signal unless it’s obtaining a new Node.
extends Area2D
@onready var area_hitbox : CollisionShape2D = $AreaHitbox
@onready var area_sprite : Sprite2D = $AreaSprite
func _on_toggle() -> void:
visible = not visible
edit: if you need to hide everything at start… just set it to not visible in the editor
I see thanks for the tips everything is so confusing as a beginner so I didnt really know how setting the visible at the start or disabling it works but now I think everytime I need Area_P to appear again I will just call the toggle function in manager. Also is the “!” operand not useful for booleans in godot or is it just in this specific case ?