Godot version:
3.2 beta1
Issue description:
This one is complicated a bit, but boils down to this:
extends Node2D
class_name Base
func _ready() -> void:
test_node()
func test_node():
pass
extends Base
onready var control = $Control
func test_node():
print(control.name)
The control will be null in this case, which is a bit unexpected. Looks like the base script is initialized and calls _ready before the inheriting script is properly initialized.
Minimal reproduction project:
ReproductionProject.zip
I guess this is expected. The onready keywork is equivalent to setting the variable at the top of the _ready function. So when your script runs it initializes things in this order:
_ready() function onready variable_ready() function Thus the variable cannot be initialized inside the parent's call to the _ready function
I also would say that this is expected behaviour, similar to C++ constructor call ordering with inherited objects.
You can solve this by calling test_node() from the child's _ready() function. Another way I did not test might be using Object's call_deferred() see here.
@KoBeWi I've managed to workaround the issue like that:
extends Base
#onready var control = $Control
var control
func _notification(what):
match what:
NOTIFICATION_INSTANCED:
control = $Control
# NOTIFICATION_READY: # same as onready
# control = $Control
func test_node():
print(control.name)
So basically the whole initialization happens on early NOTIFICATION_INSTANCED instead of syntax sugar coated NOTIFICATION_READY.
I've been thinking on migrating to this kind of technique over using onready var in fact which seems to resolve onready dependent node referencing with get_node() later on (while the scene is not even added to the tree). Talking about dependency: #30460.
I had to modify the scene tree because of wrong hierarchy of nodes, updated repro project:
ReproductionProject.zip
Still valid in 3.2.3
There's a chance it's fixed in master, but can't test due to #42440 and #42506
Most helpful comment
I guess this is expected. The
onreadykeywork is equivalent to setting the variable at the top of the_readyfunction. So when your script runs it initializes things in this order:_ready()functiononreadyvariable_ready()functionThus the variable cannot be initialized inside the parent's call to the
_readyfunction