Storing node variable in a separate variable returns null

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

In my script, I have accessed three nodes:

onready var weaponScrollContainer = $CenterContainer/InventoryBackground/VBoxContainer/HBoxContainer/Tabs/WeaponScrollContainer
onready var armorScrollContainer = $CenterContainer/InventoryBackground/VBoxContainer/HBoxContainer/Tabs/ArmorScrollContainer
onready var itemScrollContainer = $CenterContainer/InventoryBackground/VBoxContainer/HBoxContainer/Tabs/ItemScroll

these nodes are stored as weaponScrollContainer, armorScrollContainer, and itemScrollContainer. I switch between these three nodes in the scene, so I created a variable called “currentTab” to store the node that is currently active.

When I try to run this script, however:

    if currentTab != weaponScrollContainer:
       currentTab.visible = false
       currentTab = weaponScrollContainer
    currentTab.visible = true

It raises an error saying currentTab is null. I was absolutely baffled by this, and when I printed the currentTab variable it printed null for the first iteration, then the correct node for every following iteration.

I have no idea what could cause this, any help?

Hi, I don’t know how much I can help but I want to understand this. In the second line of the if statement, what type is the current tab? Before that if, do I initialize the variable to the required node type?

estebanmolca | 2020-06-10 03:07

I’m honestly not super familiar with types. I initially defined currentTab as a blank global variable. How do I initialize currentTab to be the correct node type? The exact error is : “Invalid set index ‘visible’ (on base: Nil) with value of type bool”

DigitalDrako | 2020-06-10 03:20

A type is defined for the variables in this way: var var_name: Type Although it is not necessary, is a way to tell godot in advance what type of variable you are working with. In the manual it is well explained, but in this case, initialize the variable to one of the three nodes you want to reference, before the if statement. Example:
currentTab = weaponScrollContainer
Now that godot knows what type currenTab is and where it points, it makes sense to put: currentTab.visible = true or currentTab.visible=false (As long as the node current_tab points to has the “visible” property)

estebanmolca | 2020-06-10 03:54

Unfortunately you didn’t state how you initialize currentTab and from where the rest of your script is called, e.g. from _process (i.e. every frame) or from _ready (i.e. once in the beginning), but if it’s properly initliazed your code should work:

onready var weaponScrollContainer = # ...
onready var armorScrollContainer = # ...
onready var itemScrollContainer = # ...
onready var currentTab = weaponScrollContainer

njamster | 2020-06-10 17:01

Currently, currentTab is initialized as weaponScrollContainer and the given code is being called in a match statement within the _process function.

If you’re interested here’s the full relevant code:

var state = WEAPONS
var currentTab = weaponScrollContainer

onready var weaponScrollContainer = #
onready var armorScrollContainer = #
onready var itemScrollContainer = #

enum{
	WEAPONS,
	ARMOR,
	ITEMS,
}

func _process(delta):
	if Input.is_action_just_pressed("Inventory"):
		self.inventory_active = !inventory_active
	match state:
		WEAPONS:
			weapons_tab()
		ARMOR:
			armor_tab()
		ITEMS:
			items_tab()

func weapons_tab():
	check_current_tab(weaponScrollContainer)
	weaponScrollContainer.visible = true

func check_current_tab(tab):
	if currentTab != tab:
		currentTab.visible = false
		currentTab = tab

I know visible is being set correctly too because if I set it manually (not using currentTab) it works fine. Thanks for the help so far guys

DigitalDrako | 2020-06-10 17:43

:bust_in_silhouette: Reply From: njamster

Turn currentTab into an onready var and make sure it’s defined after weaponScrollContainer:

onready var weaponScrollContainer = # ..
onready var armorScrollContainer = # ..
onready var itemScrollContainer = # ..

onready var currentTab = weaponScrollContainer