Mosasaur What is better? Try to emit a signal from the player script directly to the label script, or connect variables with the global, or game scripts?
As stated by Hartwell , you are not updating the Label constantly and it won't change text. Your question is how you do it, right?
I generally try to avoid globals, when there is another solution. And use them when only neccessary, or when their use makes sense.
Generally the rule is signal up (signal to parents and siblings) call down (functions of children)
Setter function is a very neat way to do this, they are called whenever their variables change, and you can do anything inside them
In the player script you can do this:
# Beware that, with export vars, the set function is also called first thing,
# even on the default value, so try not to access other nodes,
# as they will not be ready/instantiated yet.
# A workaround can be to have @export var default_health,
# and another var health with setter function
# Then inside _ready() you do health = default_health
# That was only a solution to problem you might face someday, in a different context
@export var health = 200:
set(value):
# Whenever you try to change the health value,
# this gets called and the below code is executed
health = value
# A signal can carry information too, such as health
emit_signal("health_changed", health)
signal health_changed(health)
In Game script:
@onready var text = $ui/Health_panel/text_hp2
@onready var player = $Player # or wherever you Player node is in the Game node tree
# The neat thing about _ready() is that it is called AFTER every child node is ready
# Put that in mind and you can traverse the mine field called scene tree :')
func _ ready():
# connect signals, you can do it in the editor too via signals tab
# connect the health_changed signal, from the player, to the update_health(new_health) function in the health label
player.health_changed.connect(text.update_health)
# Beware that since the children nodes were ready first,
# if the player emitted a signal( which it did in the set function of the export var),
# nothing happens because the signal was not connected yet
text.update_health(player.health) # Neat way to update it first thing and show the health at the start
# A scum elitist would do player.health = player.health
# knowing the set function will be called and emit the already connected signal xD
Now change the update_health function in the label script to something like this
func update_health(new_health):
text = " Player Health: " + String.num(new_health) # Both sides need to be String type
Tada, you have a label that updates whenever the player's health change
Note: The neat thing about signals, is that it separates code logically. So you can cannect the signal to the gui that holds a label and health bar for example, and update both. Or you can connect the signal to another function in the game scene which check the health, and accordingly alert some types of enemies like blood seekers for example. You can go wild with signals!
Also notice that you are only updating the label when the health changes, and not ever frame. Much optimization.
I hope that was helpful with the explanations π
Edit: Correct here and there, add the last notice.