When I run the program, for some reason the set function is executed first and because the nodes are not loaded, an error occurs
Invalid set index ‘texture’ (on base: ‘Nil’) with value of type ‘Nil’.
At the same time, everything works in the editor.
Look at this code:
@tool
extends Area2D
class_name ItemNode
@export var ITEM: InventoryItem: set = _set_item
@onready var textureRect: TextureRect
func _set_item(value: InventoryItem):
ITEM = value
if value != null:
textureRect.texture = ITEM.image
else:
textureRect.texture = null
func get_amount():
return ITEM.amount
Yes, there is no problem with deleting this code, it is just much more convenient to work this way everything is updated at once. I am just wondering what this is connected with? The set() function is executed first than _ready(), while nothing is written in ITEM
The error comes because you are trying to modify a parameter of the variable textureRect, but textureRect is null because you never assign a value to it.
Just assign a TextureRect node to your variable textureRect.
The debugger says that all variables are null, although everything is defined in the inspector. Is it a feature of the engine that set() is executed before _ready()?
Yes, @export vars are set immediately when the scene is instantiated (pretty much right when _init() is called on the node), but the _ready() function and @onready vars aren’t processed until after the node is added to the tree.
So, you’re simply going to need to assume textureRect could be null, and then make a _ready() function which sets the texture.
Something like this should work:
@export var ITEM: InventoryItem: set = _set_item
@onready var textureRect: TextureRect = $Texture
func _ready():
_update_texture()
func _set_item(value: InventoryItem):
ITEM = value
_update_texture()
func _update_texture():
if not is_instance_valid(textureRect):
return
if ITEM != null:
textureRect.texture = ITEM.image
else:
textureRect.texture = null
Yes it works if not is_instance_valid(textureRect):return
Thank you!
But i dont understand why the set() function is called at all. Like first all variables are declared with null and at this moment set() is called, and only then something is written to them?
Anyway, even a variable that is declared via @export ITEM in debugger = null
You need to understand what exactly the @export and @onready annotations are doing.
A variable with @export won’t magically have its values filled in at the moment the node is created, but shortly after creation, the code which instantiates the scene will come along and assign your exported values to your @export vars. This is why the setter is called.
@onready vars work similarly, but they are assigned later, after the node has been added to the tree (and just before its _ready() function is called). Before then, they’ll have some default value (null or 0 or [], depending on the type).