JeremyPage
JeremyPage

Reputation: 1

Godot - Missing Nodes

This is difficult to explain with typing...

I have a GameController scene (Node2D) that holds 3 instanced scenes within:

In the main scene (Level1.tscn) I instance the GameController scene and it "works" fine. The header bar is there with the score/label and the custom mouse cursor is there and the message box is there (but I have it hidden by default but if I toggle its visibility in the remote it will show up).

Here's where my confusion comes in...

If I attempt, in the GameController script, to manipulate any of those nodes in the GameController scene (the mouse, header, messages) they return as null and will throw an error. For example; if I try to update the score in the $HeaderBar/Control/score I get the following:

Invalid set index 'text' (on base: 'null instance') with value of type 'String'.

The code completion will autofill the node names as I type them (so it recognizes them in the group) but any attempt to reference/use them in script throws similar errors to above.

I'm very new to Godot so I'm sure it's just some misunderstanding I have on how this type of thing works but I'm stumped! Any insight is much appreciated!

UPDATE

I will try to simplify my explanation a bit (I have made some changes). Okay here is the object script:

extends StaticBody2D

onready var main = load("res://scenes/MainGame.gd").new()

func _ready():
    pass

# mouse [left] clicked on object
func _on_trigger_input_event(viewport, event, shape_idx):
    if Input.is_action_just_pressed("left-click"):
        main.display_message("you [left] clicked on the object!")

the call to main.display_message() works. It does call the function but here is that function in the MainGame.gd

extends Node2D

onready var box = $Message/Control
onready var label = $Message/Control/Label


func _ready():
    # hide the mouse cursor (will use custom cursor)
    Input.set_mouse_mode(Input.MOUSE_MODE_HIDDEN)
    
func display_message(msg):
    label.text = msg
    box.visible = true

It errors out because label (and box) are null. If I call display_message from the _ready function (in the MainGame.gd) it works as it should. Call it from outside (in the Object.gd) and the nodes are null for some reason.

Upvotes: 0

Views: 690

Answers (1)

Theraot
Theraot

Reputation: 40295

This instances the scene as expected:

onready var main = load("res://scenes/MainGame.gd").new()

However, this code will run when the instanced scene is added to the scene tree:

onready var box = $Message/Control
onready var label = $Message/Control/Label


func _ready():
    # hide the mouse cursor (will use custom cursor)
    Input.set_mouse_mode(Input.MOUSE_MODE_HIDDEN)

Yes, both onready variables and _ready will run when this is added to the scene tree.

And when do you add main to the scene tree? I don't see where.

Then when you do this:

main.display_message("you [left] clicked on the object!")

Both box and label will still be null (which is the default value).

Thus, add it to the scene tree, for example:

func _ready():
    add_child(main)

Except that does not work either, does it? Look at the code again:

onready var main = load("res://scenes/MainGame.gd").new()

You are instancing a script. A script. Not a scene. It will not have its children nodes and so on. You want to instance a scene, for example:

onready var main = load("res://scenes/MainGame.tscn").instance()

However, I find it odd that you are doing this in a StaticBody2D. I don't think it makes sense that MainGame belongs to a StaticBody2D.

I suspect, you are instancing MainGame in multiple places expecting it be the same instance. But it is not the same instance, it is a new instance.

Here is where I suggest you make MainGame into a autoload, so there is a single instance that you can access from anywhere. However, perhaps that is not right either. Perhaps you should use a Signal Bus. See Why does this variable keep returning to its original value? which had a similar problem (they where trying to open a door, you are trying to show a message, but still).

Upvotes: 0

Related Questions