Can't read parent's variable from child node

:information_source: Attention Topic was automatically imported from the old Question2Answer platform.
:bust_in_silhouette: Asked By lightspot21

Hello,

I’m making a scene which consists of 2 nodes, one the root (an Area2D named Ship) and the other a child to it (an AnimatedSprite named ShipTypes).
The Ship node has a script that gives a random value to the ship_type variable, while ShipType’s script holds a reference to the parent Ship node. When attempting to read ship_type from the parent to check in the match statement, the child reads 0 instead of the parent’s random value. Why could this be happening?

Thanks in advance.

Code (parent):

extends Area2D

# Available ship types
enum ship_types {CAPITAL = 0, HOSPITAL = 1, DESTROYER = 2}

# Chosen ship type
var ship_type: int

func _ready():
    # get new random seed
    randomize()
    # pick a type at random
    var ship_type: int = randi() % ship_types.size()

Code (child):

extends AnimatedSprite

var base_ship

# Called when the node enters the scene tree for the first time.
func _ready():
base_ship = $"../"
match base_ship.ship_type:
	base_ship.ship_types.CAPITAL:
		animation = "capital_ships"
		# pick a random capital ship as a form
		frame = randi() % 4

	base_ship.ship_types.HOSPITAL:
		animation = "hospital"

	base_ship.ship_types.DESTROYER:
		animation = "destroyer"
:bust_in_silhouette: Reply From: wombatstampede

this is simple:
You redefine the variable in local context inside _ready().
So ship_type is defined two times: The “global” declaration (#1) and the local variable (#2) inside _ready() which is discarded after use (therefore the assigned value is gone).

Replace the assignment line in _ready() with:

ship_type = randi() % ship_types.size()

(so basically remove the var prefix)

I did remove the var as instructed, but no dice sadly :frowning: The value seen is still 0.

lightspot21 | 2019-12-08 23:52

To my knowledge _ready() of child nodes is called before _ready() in the parent node. To assure that all child nodes are available and ready when the handler is called in the parent.
SceneTree — Godot Engine (3.1) documentation in English

An extra notification, “ready” ( _ready() callback in GDScript) is
provided for convenience, when a node and all its children are inside
the active scene.

In your case the ship_type isn’t initialized at the time you call it.

You could instead put that value initialisation inside an _init() handler in the parent or let the child init the value and (if needed) write it back to the variable in the parent.

wombatstampede | 2019-12-09 08:16

The _init() method worked! Many, many thanks for that!

lightspot21 | 2019-12-10 11:08