Issue Updating Texture In Separate Scene

Godot Version

4.2.1

Question

I am having some issues changing textures when I press a button. To be clear I figured it out if I build everything out in the main scene and have the code all running in one script. The error occurs when I am trying to separate the scenes and scripts to clean some things up out of the main game script.

-In the main scene. I have the root node → CardUI in the tree.
-In the CardUI scene I have 5 CardSpaces and the tree looks like this for all 5: CardUI->MC->CardSpaces->CardSpace1->CardImage

The error occurs here when I press the button I have setup:

class_name CardUI
extends CanvasLayer


func update_card_image(card_name, card_index):
	var card_image = get_node("MC/CardSpaces/CardSpace" + str(card_index) + "/CardImage")
	if DeckScript.card_sprites.has(card_name):
		var sprite_path = DeckScript.card_sprites[card_name]
		var texture = load(sprite_path)
		card_image.texture = texture
	else:
		print("Sprite not found for card:", card_name)

The Deck script is where I store all the paths to the card images. I imported them all as png into the project.

Like I said I was able to build out the same tree path with the Sprite 2D in the main game scene and it ran when I have the above function in the same script. It gets to the point of setting the texture and errors out because the card_image is null. I have tried to set an @onready to find the path to the node instead of using get_node() but it still sets to null when the game runs.

Thanks for any insight or guidance :slight_smile: I am still new and jumping between some tutorials and reading the documentation in the editor to learn!

If you want to see the Deck code here it is:

class_name Deck
extends Node

var card_sprites: Dictionary = {
	"C2": "res://assets/Sprites/C2.png", 
	"C3": "res://assets/Sprites/C3.png",
	"C4": "res://assets/Sprites/C4.png",
	"C5": "res://assets/Sprites/C5.png",
	"C6": "res://assets/Sprites/C6.png",
	"C7": "res://assets/Sprites/C7.png",
	"C8": "res://assets/Sprites/C8.png",
	"C9": "res://assets/Sprites/C9.png",
	"C10": "res://assets/Sprites/C10.png",
	"CA": "res://assets/Sprites/CA.png",
	"CJ": "res://assets/Sprites/CJ.png",
	"CK": "res://assets/Sprites/CK.png",
	"CQ": "res://assets/Sprites/CQ.png",
	"D2": "res://assets/Sprites/D2.png",
	"D3": "res://assets/Sprites/D3.png",
	"D4": "res://assets/Sprites/D4.png",
	"D5": "res://assets/Sprites/D5.png",
	"D6": "res://assets/Sprites/D6.png",
	"D7": "res://assets/Sprites/D7.png",
	"D8": "res://assets/Sprites/D8.png",
	"D9": "res://assets/Sprites/D9.png",
	"D10": "res://assets/Sprites/D10.png",
	"DA": "res://assets/Sprites/DA.png",
	"DJ": "res://assets/Sprites/DJ.png",
	"DK": "res://assets/Sprites/DK.png",
	"DQ": "res://assets/Sprites/DQ.png",
	"H2": "res://assets/Sprites/H2.png",
	"H3": "res://assets/Sprites/H3.png",
	"H4": "res://assets/Sprites/H4.png",
	"H5": "res://assets/Sprites/H5.png",
	"H6": "res://assets/Sprites/H6.png",
	"H7": "res://assets/Sprites/H7.png",
	"H8": "res://assets/Sprites/H8.png",
	"H9": "res://assets/Sprites/H9.png" ,
	"H10": "res://assets/Sprites/H10.png",
	"HA": "res://assets/Sprites/HA.png",
	"HJ": "res://assets/Sprites/HJ.png",
	"HK": "res://assets/Sprites/HK.png",
	"HQ": "res://assets/Sprites/HQ.png",
	"S2": "res://assets/Sprites/S2.png",
	"S3": "res://assets/Sprites/S3.png",
	"S4": "res://assets/Sprites/S4.png",
	"S5": "res://assets/Sprites/S5.png",
	"S6": "res://assets/Sprites/S6.png",
	"S7": "res://assets/Sprites/S7.png",
	"S8": "res://assets/Sprites/S8.png",
	"S9": "res://assets/Sprites/S9.png",
	"S10": "res://assets/Sprites/S10.png",
	"SA": "res://assets/Sprites/SA.png",
	"SJ": "res://assets/Sprites/SJ.png",
	"SK": "res://assets/Sprites/SK.png",
	"SQ": "res://assets/Sprites/SQ.png",
	"JB": "res://assets/Sprites/JB.png",
	"JR": "res://assets/Sprites/JR.png",
}
var full_deck = [
	"C2", "C3", "C4", "C5", "C6", "C7", "C8", "C9", "C10", "CA", "CJ", "CK", "CQ",
	"D2", "D3", "D4", "D5", "D6", "D7", "D8", "D9", "D10", "DA", "DJ", "DK", "DQ",
	"H2", "H3", "H4", "H5", "H6", "H7", "H8", "H9", "H10", "HA", "HJ", "HK", "HQ",
	"S2", "S3", "S4", "S5", "S6", "S7", "S8", "S9", "S10", "SA", "SJ", "SK", "SQ",
	"JB", "JR",
	]
var current_deck = []

var card_ui = CardUI.new()

func draw_card():
	current_deck = full_deck.duplicate()
	var player_cards = [new_card(), new_card(), new_card(), new_card(), new_card()]
	for i in range(player_cards.size()):
		var card_name = player_cards[i]
		card_ui.update_card_image(card_name, i + 1)
		#update_money(card_name)
	print(player_cards)
	
	
	
func new_card():
	var card = current_deck[randi() % current_deck.size()]
	current_deck.erase(card)
	return card

CardUI Tree

Looks fine to me. You might want to modify your function to narrow the issue down:

func update_card_image(card_name, card_index):
	var card_image = get_node("MC/CardSpaces/CardSpace" + str(card_index) + "/CardImage")

	if not card_image:
		print(card_index)

	if DeckScript.card_sprites.has(card_name):
		# ...

If this prints anything else than 1, 2, 3, 4 or 5, you’re calling your function with wrong arguments somewhere. If it does print 1, 2, 3, 4 or 5, your tree does not look like in the screenshot (yet or anymore) when the function is called.

(You could also set a breakpoint in the line with the print statement to halt the game and inspect the current state of your game in greater detail.)

I know I am missing something but I did get it working by setting the path all the way back from the root node. I know there has to be an easier way to do this but no combination of get_parent, get_child, or get_node works outside of that.

I used:

var card_image = get_node("/root/Game/CardUI/MC/CardSpaces/CardSpace" + str(card_index) + "/CardImage")