Trouble with persistent information using group reference vs node reference

Godot Version

4.2

Question

I feel like this is an unusual issue. I have an inventory system that persists through scenes. This works fine the way I have it built using code structured like this:

uiInventory = [$“…/Node2D/Player/Inventory/Inventory_BG/Inv_Slot_0”,“…/Node2D/Player/Inventory/Inventory_BG/Inv_Slot_2”]

I came into a need to need it more dynamic, so I no longer wanted to reference the node directly through get_node. Instead I grouped the inventory slot “InventorySlot”

I then created a reference to this like so:

var grpInventorySlot = get_tree().get_nodes_in_group(“InventorySlot”)

and replaced the above code like this:

uiInventory = [grpInventorySlot[0],grpInventorySlot[1]]

I printed both values and ensured they were still referencing the same nodes, and they were.

Now the problem is despite what I believe to be essentially the same code, no longer works when switching scenes. It states the data has been freed and cant access a null reference.

Does anyone know why the direct node reference works, but switching to a more dynamic group call does not?

Thanks

Is this an autoload? It would help to explain your scene dynamic a little more, how does the uiInventory stick around while the “Player/Inventory” are freed?

The path based node references will not work in the same implementation, what else has changed?

Yes, the inventory is on autoload and there are two parts to the inventory:

inventory - holds the array of the item its holding
uiInventory - holds the image of the item to show on the UI

When entering a portal to go to a new scene this function is called on the Inventory.gd

 func SaveInventoryUiImages():
	for i in range(uiInventory.size()):
		invImages[i] = uiInventory[i].texture

and on the _ready() of the Player.gd Inventory.UpdateInventoryUI() is called:

func UpdateInventoryUi():
	uiInventory = [$"../Node2D/Player/Inventory/Inventory_BG/Inv_Slot_0",$"../Node2D/Player/Inventory/Inventory_BG/Inv_Slot_1",$"../Node2D/Player/Inventory/Inventory_BG/Inv_Slot_2",$"../Node2D/Player/Inventory/Inventory_BG/Inv_Slot_3",$"../Node2D/Player/Inventory/Inventory_BG/Inv_Slot_4",$"../Node2D/Player/Inventory/Inventory_BG/Inv_Slot_5",$"../Node2D/Player/Inventory/Inventory_BG/Inv_Slot_6",$"../Node2D/Player/Inventory/Inventory_BG/Inv_Slot_7"]
 	for i in range(invImages.size()):
 		uiInventory[i].texture = invImages[i]

All that has changed is instead of uiInventory being assigned to those direct node references, it was being assigned via the group as i demonstrated above.

I’m hoping that is enough information to point me in the right direction, im very much at a loss on this one.

And the group implementation should look like this right?

func UpdateInventoryUi() -> void:
 	uiInventory = get_tree().get_nodes_in_group("InventorySlot")
 	for i in range(invImages.size()):
 	 	uiInventory[i].texture = invImages[i]

SaveInventoryUiImages should work the same.


This part is what gives me pause as grpInventorySlot is already the array you want so re-creating an array by indexing individually is unnecessary, the extra variable is stale if it’s kept between scene changes.

var grpInventorySlot = get_tree().get_nodes_in_group(“InventorySlot”)

and replaced the above code like this:

uiInventory = [grpInventorySlot[0],grpInventorySlot[1]]

Thank you, you are correct. I was making it more complicated than it needed to be by introducing the grpInventorySlot array. Simply assigning uiInventory to the group works as I would expect.

Very much appreciate your help, spent hours looking at this one to no avail.

1 Like

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