Invalid assignment of property or key 'text' with value of type 'String' on a base object of type 'int'.

4.4 Godot

I’m only new to this but i’m trying to get my UI to update the numbers on it but other than in-game events like collecting coins i can’t do it manually, I can set the int but until i collect one in game i can’t add it to in _ready()?

This is my code:

extends CanvasLayer

class_name UI

References

@onready var Lives = $LIVES
@onready var Score = $SCORE
@onready var Coins = $COINS
@onready var TimeNo = $TIMENO
@onready var WorldNo = $WORLDNO
@onready var Timenode = $Timer
@onready var total_time_seconds : int = 400

@export var WorldName: String

func _ready():
Coins = 2
update()
WorldNo.text = WorldName
Timenode.start()

func set_score(points):
Score.text = “%d” % points

func set_coins(coins):
Coins.text = “%02d” % coins

func set_lives(lives):
Lives.text = “%02d” % lives

func _on_timer_timeout():
total_time_seconds -= 1
var m = int(total_time_seconds / 60)
var s = total_time_seconds + m / 60

TimeNo.text = "%03d" % s

func update():
if Coins != null:
set_coins(Coins)

start by setting variable types. if you drag the node into the script while pressing control, it will create a line for assigning a reference, and do so correctly.
it should look like this:

@onready var Lives : Control = $LIVES

this tells the engine (and you) that the variable is of type Control. this depends on the type of node you are using, it could be a label, it could be a timer.

the problem here is very clear, Coins is a node, but you are trying to assign a number to it.
if it is supposed to be a label, you are supposed to assign the “text” variable (and convert to string)

Coins.text = str(2)

or

Coins.text = "2"

you do it correctly here:

don’t use this syntax, it’s confusing for no reason. and the % symbol should be used to place text inside a string, like for a message that says: “you have % points”. this doesn’t need it, as there is nothing else written.
use str() instead:

Score.text = str(points)

you should use the alternative to %, format(), which is cleaner and allows for more replacements:


"you have {0} points".format({"0": points})

this just makes no sense.
Coins is a reference to the node COINS.
set_coins() assigns a value to the text of COINS.
you are passing a reference to COINS to set_coins which then sets that reference to the text.

I recommend that you declare types for everything, starting with this. make coins an integer so that it only accepts numbers. the editor will warn you if try to pass anything that is not a number to it.

func set_coins(coins : int):

I did get it working jesusemora, but it’s getting other scripts to talk to it.

As it is for now I’m trying a singleton layout to send data around to transfer between scenes.

My layout is:
SceneData.GD

extends Node

var spawn_point: Vector2
@export var player_mode: Player.PlayerMode
var points_global : int
var coins_global : int
var lives_global : int
var time: int

that talks to the Level manager so it can send the data to the level scripts.
LevelManager.GD

extends Node

class_name LevelManager

@onready var PLAYER_SCENE = preload("res://Scenes/player.tscn")

var points = 0
var coins = 0
var lives = 0

@export var ui: UI
@export var player: Player

func _ready():
player.points_scored.connect(on_points_scored)

if SceneData.points_global != 0:
	SceneData.points_global = points
	ui.set_score(points)
if SceneData.lives_global != 0:
	SceneData.lives_global = lives
	ui.set_lives(lives)
if SceneData.coins_global != 0:
	SceneData.coins_global = coins
	ui.set_coins(coins)
	
player.points_scored.connect(on_points_scored)

func on_life_collected():
  lives += 1
  ui.set_lives(lives)

func lose_life():
  lives -= 1
  ui.set_lives(lives)

func on_points_scored(points_scored: int):
   points += points_scored
ui.set_score(points)

func on_coin_collected():
  $Coin.play()
  coins += 1
  points += 100
  ui.set_score(points)
  ui.set_coins(coins)

func save_state():
  SceneData.points_global = points
  SceneData.coins_global = coins

func load_state():
  points = SceneData.points_global
  coins = SceneData.coins_global
  ui.set_score(points)
  ui.set_coins(coins)


func fresh_start():
  pass

but the problem still is i can get the information to be there, but until i jump on an enemy or collect a coin it doesn’t show on the UI, so it’s getting it to send it to the UI to update the information on screen and doesn’t want to pass the data to the SceneData (which is an autoload script) so then in the next level i can pull it from it.