Instantiated object calls null when grabbing unique nodes from scene

Godot Version

v4.2.2

Question

I have a scene where I call menu items (cards) into the scene, and then it sets some @onready vars to the appropriate unique nodes (like %Player), but it throws an error:


I dont know what’s wrong here : /

Here’s more of the code/structure

image


image

The card script is in this scene object node thing, which gets instantiated by the Game node:
image

I’m stuck if I can’t get these cards to instantiate : |

Also making them local again and not instantiate it doesnt fix it, I dont know what happened

Heres where randify() is getting called

1 Like

can you start again and go to the remote-scene tree and make a screenshot of that with all children shown. Also can you show all the code of the randify-method?

And a little Advice:
If you want UI elements to always be on screen, also when the camera is moving: You dont have to make them children of the camera. Instead you can use a CanvasLayer as parent of the UI-Nodes. CanvasLayer always move with the camera if its a child or not

2 Likes

What do you mean by the remote scene tree? Do you just mean the top node? (That’s the “game” node)

Randify:


Oh and here’s all the nodes, if the node tree is what you mean by scene tree

Unique names can’t be used this way, honestly them working with any parent node is buggy at best and not how it’s supposed to be used. I’d recommend @export instead

2 Likes

I don’t understand how I could use @export to access a parent or grandparent node, the article doesnt mention it and I tried searching it but couldnt find anything. The unique name references were actually working fine too before in the same situation, I don’t know why they were though. What do you mean using @export?

If I understand what you’re trying to do correctly (add the cards to the scene via code at runtime, meaning Cardcontainer is empty to start) I would add the onready variables into the Game Node, or whichever node is responsible for spawning the cards. You keep those variables in the card script as well, just remove the @onready part.

When it’s time to spawn a card, you set the card’s references to those nodes using the spawner’s onready references, the same time you’re setting things like their text and textures.

Something like this in the Game script:

@onready var card_container := %Cardcontainer
@onready var player := %Player
#the rest of them

const CARDS := preload("res://propcard.tscn")

func add_a_button():
    var new_card := CARDS.instantiate()
    new_card.player = player
    #the rest of them
    card_container.add_child(new_card)

And your Card to something like

@export var player : Node
#the rest of them

The main reason to do them as export variables is that it makes it easier to test, because you can manually add cards to your scene (to check that they do what they’re supposed to) and set those references in the editor, without needing to worry about the script that normally adds them needing to do that for you. If you don’t plan to use that functionality in this case, you can just leave off the @export bit

Again, this does assume you’re adding your cards from code, rather than having the same number of cards in the scene every time. If this is a “pick from 3 upgrades” sort of situation you can do this easier with just export variables and updating them whenever you show the options.

For more on Export vars, this bit of the docs is relevant

3 Likes

It’s throwing an error with this function now and I dunno what to do about it




It doesn’t realize that I’m setting the variable I think

Actually the : instead of = fixed it with I think that means static typing. Thank you!!! I’m really tired and probably wouldn’tve figured it out

1 Like

Make sure to paste code to the forum, it will make helping you and creating eamples easier

Instead of @onready and the path to the object you want, use @export and it’s type

extends Button

@export var scac: Container
@export var player: RigidBody2D
@export var ctext: Control # ?? not sure the type on this one, doesn't have to be exact
@export var SBC: VBoxContainer
@export var gamen: RigidBody2D # same as player?
@export var CTexture: TextureRect

Once you save the script like this you can select your card, and fill in the exported variables via the Inspector.

Like this example @export var speed: float in the dodge the creeps tutorial.

2 Likes

This topic was automatically closed 30 days after the last reply. New replies are no longer allowed.