How to put a text in a label through code in Godot 4.3

Godot Version

Godot 4.3

Question

Basically, i’m following a tutorial, and it reaches a point where it says to put a “set_text” into the code, but, i think this set_text doesn’t exist anymore? Look at the example below:

extends CanvasLayer

@onready var CurrentAmmoLabel = $VBoxContainer/HBoxContainer/CurrentAmmo
@onready var CurrentWeaponLabel = $VBoxContainer/HBoxContainer2/CurrentWeapon

func _on_weapons_manager_update_ammo(Ammo):
   CurrentAmmoLabel.set_text(str(Ammo[0])+" / "+ str(Ammo[1]))

func _on_weapons_manager_weapon_changed(Weapon_Name):
   CurrentWeaponLabel.set_text(Weapon_Name)

See where there’s the set_text? How can i substitute this but still keeping the overall structure of this code? My main problem sometimes with changing lines of code is that, as a beginner, i can’t really change something, as small as it is, and expect everything to work as planned…

If anyone can help with this, it would be much appreciated

Check docs, use:

label.text = "new text"
func _on_weapons_manager_weapon_changed(Weapon_Name):
	CurrentWeaponLabel.text = "Weapon_Name"

Like so?
If it is, what does it mean this error text?:

Invalid assignment of property or key ‘text’ with value of type ‘String’ on a base object of type ‘Nil’.

Can you send what your node tree looks like?


This is the first one, “view_model_cam” is the camera that renders the weapons on the screen


The second one, the UI down there is where the ammo and current weapon labels are shown on the screen

the functions “_on_weapons_manager_update_ammo(Ammo):” and “func _on_weapons_manager_weapon_changed(Weapon_Name):” are signals that were imported from scripts of the “Weapons_Manager” in the view_model_cam

The error message means that CurrentWeaponLabel does not have a value. So you’ll have to look through the rest of your code and figure out why it does not.

I mean, it could be, but wouldn’t this already be the value?:

@onready var CurrentWeaponLabel = $VBoxContainer/HBoxContainer2/CurrentWeapon

And even if it wasn’t, it isn’t something complex, “CurrentWeaponLabel” is literally just calling a label already defined and set on the screen, i simply want to put the name of the weapon that’s equipped on the player in this label. The same goes for ammo, but for ammos

What you send looks good and must work, so without diving dipper we can’t help. Can you post your project to github or smth like that?

Well i never tried this before, and since i’m of a foreign country, maybe you wouldn’t understand some things. But i will try posting the project then

Git is a great tool you should check it. The syntax of gdscript one and only so any person can read it (if you name functions and variables in english). So don’t worry, english is not my first language too.

Also, before using the github, i just wanna point out the “Nil” thing is kinda bothering me, as to why could it be that this is appearing? I don’t think it can be perceived only by looking at the code that i posted, but maybe i could add something or change something so this “Nil” disappears?

In your code @onready must make a label object, but if it tells that it’s Nil that means that somewhere there might be smth that deletes the object. So without full code we can’t help(
Maybe give a link to tutorial, what if there is something not right?

How can i import my project into github? I’ve just created my account but i don’t understand how this works :frowning:

Try this tutorial

How my game handles labels on the UI, in Godot 4.3, such as for my health bar is like this:

extends MarginContainer

@onready var hp_bar: ProgressBar = $“%HpBar”
@onready var hp_label: Label = $“%HpLabel”

You need to set (in the scene tree) the label to “access by unique name” by right-clicking the label.

Then to change the label, it uses this function:

func player_hp_changed(hp: int, max_hp: int) → void:
hp_bar.max_value = max_hp
hp_bar.value = hp
var hp_ratio: int = ((hp_bar.value * 100) / hp_bar.max_value)
hp_label.text = “HP: %d/%d { %d%% }” % [hp, max_hp, hp_ratio]

When the label is first brought into the main scene, it calls this initialization function:

func initialize(player: Entity) → void:
if not is_inside_tree():
await ready
player.fighter_component.hp_changed.connect(player_hp_changed)
var player_hp: int = player.fighter_component.hp
var player_max_hp: int = player.fighter_component.max_hp
player_hp_changed(player_hp, player_max_hp)

What this means is that the “await ready”, is waiting for the player character to be created.

Then once it is created, it connects a signal generated in the fighter_component, called hp_changed. Any time that is called, it runs the first function (player_hp_changed) which is what updates the label.

Then in fighter_component (a member class), it has:

signal hp_changed(hp, max_hp)

Then in:

var hp: int:
set(value):
hp = clampi(value, 0, max_hp)
hp_changed.emit(hp, max_hp)
if hp <= 0:
var die_silently := false
if not is_inside_tree():
die_silently = true
await ready
die(not die_silently)

So what this does, is that whenever the player object has their health increased or decreased, it runs this function. Then it emits a signal of hp_changed, which is caught by the function player_hp_changed, and then updates the label on the UI.

Hope some of that helped you.

2 Likes

I will definitely have a look at this later on, thanks!

https://github.com/MechaBRO/MagulaProject

I think i’ve done it, i will probably make a topic citing this link also, so people can more easily acess it

I can’t see your github project. You probably need to make it public, see guide

It’s now oficially public, thanks! i thought it was automatic to make a public project

He’s right when your UI first gets signal to change labels it will give this error but then it works fine. The simple solution is to move UI node up the scene tree so it would be initialized before weapon manager.

like this
image