Hello all,
I have a shop system which I am trying to finish up, but I can’t seem to figure out how to go from the buy button to accessing the custom resource (information where the item is stored) to updating the display (which is in another scene).
The “PlayerProperties” is a global resource which holds data such as “money” and “chickenCount”.
Now, this is where the problem lies: the code runs fine here and doesn’t throw an error; however, the function “update_display()” doesn’t seem to do anything.
This is “stat_display.gd”:
extends Node
@onready var moneyDisplay = $menu/top_right_display/base_menu_screen/NinePatchRect/MarginContainer/statDisplay/HBoxContainer/chicken_count
@onready var chickenCountDisplay = $menu/top_right_display/base_menu_screen/NinePatchRect/MarginContainer/statDisplay/HBoxContainer2/money
func _ready():
#PlayerProperties.money = str(10)
var moneys = PlayerProperties.money
#update_display()
#print(moneys)
func update_display():
print("runnning")
print("money is: " + str(PlayerProperties.money))
if moneyDisplay.text:
moneyDisplay.text = str((PlayerProperties.money))
chickenCountDisplay.text = (str(PlayerProperties.chickenCount) + " / " + str(PlayerProperties.chickenCapacity))
I have racked my brain for days and can’t figure it out. Any help is greatly appreciated!
If you just load the script that is attached to the node you want to interact with, Godot doesn’t know which exact node you mean because there could be multiple nodes with tht script
You will need to get the node you are looking for. If there is only ever one instance of the script stat_display.gd, you can use a singleton:
# stat_display.gd
static var this
func _ready():
this = self
Otherwise, I don’t think there is a way other than using get_node(…) with the full node path
I’ve tried to make the stat_display.gd a global, which fixes the update_display function not running, but then it can’t find:
@onready var moneyDisplay = $menu/top_right_display/base_menu_screen/NinePatchRect/MarginContainer/statDisplay/HBoxContainer/chicken_count
@onready var chickenCountDisplay = $menu/top_right_display/base_menu_screen/NinePatchRect/MarginContainer/statDisplay/HBoxContainer2/money
And get_node(…) won’t work since the script extends a resource:
i.e this:
var statDisplay = get_node("res://stat_display.gd")
returns this: Parser Error: Function “get_node()” not found in base self.
So I think using a singleton here is a good solution or at least part of one - but you might need to change which scripts try to access the relevant variables & nodes, because from what I know singletons are loaded into the root viewport/scene tree before any other nodes and thus trying to reference those other nodes when the singleton is created like this (in it’s @onready) won’t work. And as for the parser error - if you still want to use get_node for these variable definitions, you could have stat_display.gd just extend Node (the default) and not Resource unless you have specific reasons to use Resource.
Something you could do is like for the node you want to define moneyDisplay as, attach a unique script to that node which declares it a unique class and give that class a static var which represents itself, like Instance; so could be like:
and the variable moneyDisplay could be accessed this way as MoneyDisplay.Instance by other scripts.
However the method that you’re trying to use to define moneyDisplay and chickenCountDisplay might work without much tweaking if instead you define them in the singleton’s func _ready(), but with a timer which runs before their definition and stalls the singleton so that the variables are only defined after the timer has run out and the nodes that you currently can’t access with @onready have been loaded in while the timer was ticking, so like in the singleton:
extends Node
func _ready() -> void:
await get_tree().create_timer(0.1).timeout;
var moneyDisplay = $menu/top_right_display/base_menu_screen/NinePatchRect/MarginContainer/statDisplay/HBoxContainer/chicken_count
var chickenCountDisplay = $menu/top_right_display/base_menu_screen/NinePatchRect/MarginContainer/statDisplay/HBoxContainer2/money
using timers to solve problems like this can be problematic though in case anything depends on the timer not existing