Tool node will not recognize its own Sprite child in setter function

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

I have an NPC node that is a tool and one of its script variables has a setter function attached that takes a string and uses it to find a sprite image (saved a .PNG) in the game folder to choose its sprite. I type in something like “CITPED2” and it looks inside the folder to find PED2.PNG in the CIT folder.

enter image description here

However, the line of script that sets the texture always returns an error:

enter image description here

 Node not found: Sprite
 res://Maps/Actors/{Scripts/NPC.gd:28 - Attempt to call function 'set_texture' in base 'null instance' on a null instance.

From what I read of this error, the function is not recognizing the Sprite and returning it as a ‘null instance’. It’s weird because despite getting an error, the script does was its supposed to do. In the editor, when I change the sprite_sheet variable (and the string is a valid location), the Sprite’s Texture changes without any other problems! But running this game is impossible because that error comes up on runtime just as it does in the editor.

I’m not sure what causes it, but if I remove that line changing the texture then I don’t get the error.

The error doesn’t pop up whenever I change the sprite_sheet variable, but whenever I save or load in the node. Maybe there’s something about what happens to a tool during save time that could enlighten us, but I’m still learning how tools work.

So I’m guessing this has to do with either setter functions or how tool nodes function in the editor. I’ve been trying at this for awhile and I’m really out of ideas. I couldn’t find the help I needed.

:bust_in_silhouette: Reply From: Amir Rezaei

Did you find any solution?

:bust_in_silhouette: Reply From: Raphiell

I had a similar issue, I fixed it by adding a check if the node is in the tree in the setter.

Here is a look at multiple solutions:
https://forum.godotengine.org/23607/best-way-to-tell-if-node-is-loaded-when-exporting-variables

Another example: https://github.com/godotengine/godot/issues/30460#issuecomment-509697259

Example of what I did

export(Texture) var sprite_sheet setget set_sprite_sheet
func set_sprite_sheet(new_sprite_sheet: Texture) -> void:
	sprite_sheet = new_sprite_sheet
	if(is_inside_tree()):
		if(sprite_sheet):
			$Sprite3D.texture = sprite_sheet
		else:
			$Sprite3D.texture = null

I think the setter may run multiple times, sometimes before any children have been added? But I’m not 100% sure on that.

Similar to the second example I linked, you may need to re-set those values in the ready function.