0 votes

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"
asked Dec 8, 2019 in Engine by lightspot21 (19 points)

1 Answer

0 votes
Best answer

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)

answered Dec 8, 2019 by wombatstampede (3,193 points)
selected Dec 10, 2019 by lightspot21

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

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.
https://docs.godotengine.org/en/3.1/getting_started/step_by_step/scene_tree.html

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.

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

Welcome to Godot Engine Q&A, where you can ask questions and receive answers from other members of the community.

Please make sure to read How to use this Q&A? before posting your first questions.