Trouble displaying variables

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

I want to simply display the players current health a number through a label. I kept getting a null instance error by using get_node(), so I used godot’s autoload to get the player variables and while I didn’t get an error, now another instance of the player is spawned and the health displayed doesn’t updated when changed.
There’s likely a much simpler way I may have overlooked as i’m still a complete beginner.

UI code:

extends Node2D

var health = player.health

func _process(delta):
	$Label.text = "%s" % health

Does the player have the variable health?

magicalogic | 2022-11-30 06:50

The player has a health variable and can have it’s health updated just fine, I just can’t display that variable for the UI.

wolvertox | 2022-11-30 06:54

I wouldn’t use autoload for player if you have more than one instance. What error did you get with get_node()?

SteveSmith | 2022-11-30 07:14

that was the issue, when I used autoload in instanced a completely separate unintentional instance of the player. And when I used get_node() it’d say health was null

wolvertox | 2022-11-30 07:33

Is the Label a child of the Player Node? Did you try using the “% Access as Scene Unique Name” option, i.e.

get_node("%Label").text = "%s" % health

Can you share a screenshot of you scene tree?

I tested it real quick and it seems to work for me without issues:

Small Tree of Nodes where Label is child of Player

I then moved the Label furhter up the tree, but used the “Access as Scene Unique Name” option and it still worked with the code I wrote above:

Full Tree where the Label is a child of a CanvasLayer

Juxxec | 2022-11-30 08:08

And when I used get_node() it’d say health was null

Show us the code where you used get_node().

SteveSmith | 2022-11-30 09:55

I ended up finding an alternative and far easier method. By creating a global health variable through autoload I could simply call on it in the UI script like this

 extends Node2D

onready var num = $health
onready var fps = $fps

func _process(delta):
	fps.text = str(Engine.get_frames_per_second())

func _ready():
	var player_health = GlobalVar.get_player_health()
	update_health(player_health)

func _on_Player_health_updated(player_health): <---- connected to a signal in the player node
	update_health(player_health)

func update_health(new_value):
	num.text = str(new_value)

wolvertox | 2022-11-30 19:16

:bust_in_silhouette: Reply From: SteveSmith

health is being set at the start of the program. It’s not being changed anywhere.

:bust_in_silhouette: Reply From: Juxxec

Just emit the signal in your Player node on _ready(). There is no need to use a GlobalVar.

export(int) var max_health = 100

var health = self.max_health

func _ready():
      emit_signal("update_health", self.max_health)

func _on_took_damage(damage):
      self.health -= damage
      emit_signal("update_health", self.health)
      # ...