#I have a problem with child scripts.

19 messages · Page 1 of 1 (latest)

undone python
#

Translation to English:

I have a problem with child scripts.
For example, there is a parent script that contains a variable, and this variable is initialized — meaning it holds a reference to a node. However, when I call this variable in the child script to get this reference, it throws a Null error. Although the variable is definitely initialized in time, because right before calling the function in the child script from the parent script, I print this variable to the console, and it’s not null.

Please help, because I’ve been struggling with this for a long time. Or maybe someone can explain how to properly use child scripts, etc. I can show my script where the error occurs if needed.

sterile ether
undone python
#

Translation to English:

It might be difficult for you to understand what I’ve shown, so feel free to ask questions. Unfortunately, I don’t speak English well enough to explain it in a video.

#

In the video, I realized that maybe the problem is not exactly with the variable itself.

dusty scarab
#

I’m seeing WEAPON is defined in GameCharacterControl, not Inventory, correct? That’s the problem… if you want WEAPON in the child script, you’ll need a reference to that instance of GameCharacterControl

undone python
#

maybe I don't understand something

sterile ether
# undone python **Translation to English:** It might be difficult for you to understand what ...

(please use "reply" option if you want me to get notified 🙃)
I'd guess some GameCharacterControl._ready is called before Inventary._ready is resumed and hence the %Inventary.load_invtentary("slot") fails as its WEAPON is not yet initilized.

Comment out that %Invantory.load_invtentary("slot") call, replace the preceding print(WEAPON) with:

print("%s" % [self.get_path()])
print(" %-20s = %s" % ["self", self])
print(" %-20s = %s" % ["self.WEAPON", self.WEAPON])
print(" %-20s = %s" % ["%Inventary", %Inventary])
print(" %-20s = %s" % ["%Inventary.WEAPON", %Inventary.WEAPON])

and try making sense of the output.

dusty scarab
#

Perhaps here, to get it working, try get_parent().WEAPON

sterile ether
dusty scarab
#

Yeah tough to see that in the video, sorry - I think your ordering might be right but I’d also wonder which weapon variable is being wanted here if both parent and child scripts have their own instance

undone python
#

Translation to English:

Input_Player is also a child script of GameCharacterControl. I created it to move all key inputs there because the CharacterBody3D script was too overloaded (so to speak, script optimization).
Here’s what relates to Inventory, there is:
func _input(event):
if Input.is_action_just_pressed("Weapon1"):
%Inventary._load_inventary("slot1")
if Input.is_action_just_pressed("Weapon2"):
%Inventary._load_inventary("slot2")
if Input.is_action_just_pressed("Weapon3"):
%Inventary._load_inventary("slot3")

#

I just noticed that I spelled the word inventory incorrectly, sorry🤦

undone python
sterile ether
# undone python /root/TestMechanic/1/Game_Character_Control/InputPlayer self = ...

Yeah it's just about the order of operations. _ready is called for these nodes in the order as shown below, and in the same order the await owner.readys are resumed (assuming all these nodes run GameCharacterControl._ready).

Meaning when GameCharacterControl._ready is resumed for node 1 (InputPlayer), at that moment for nodes marked as 2/3/4/5/6 their relevant members (like WEAPON) are not yet initialized. And that's why %Inventary._load_inventary("slot1") called from node 1's _ready was throwing null reference error.

Besides, with your code note that even if %Inventary._load_inventary("slot1") would not fail/crash, it would be called six times, once for each of these nodes (which I doubt is what you want).

dusty scarab
dusty scarab
#

Obviously the intention isn’t to have two instances so something needs tidying up; if the inventory needs a weapon then declare it there and assign it in the inspector rather than extend the other class (or grab the reference/pass it in to the inventory, and so on)