Problems with how to use Signals in Code

Godot Version

Godot 4.3 [77dcf97d8]

Question

` Hello dear friends,
i have some trouble with signals in my small project.
I try to connect an enemy, player and a health bar with signals. The setup is like this:
Enemy:

signal dmg_dealed(dmg: int)


func attack(value):
	if not hit:
		hit=true
		dmg_dealed.emit(value)
		print("deals dmg: ",value)

Player:

func _on_sceen_start():
	position = tile_list[1][1].position
	curren_tile_index = [1,1]
	current_tile = tile_list[1][1]
	player_health = get_health_node()
	var enemies: Array =  get_tree().get_nodes_in_group("enemy")
	
	for enemy in enemies:
		enemy.dmg_dealed.connect(player_health.set_health.bind())

`
Health Node on Player

class_name Health
extends Node

signal max_health_changed(diff: int)
signal health_changed(diff: int)


@export var max_health: int = 3: set = set_max_health, get = get_max_health

@onready var health: int = max_health: set = set_health, get = get_health

func set_max_health(value: int):
	
	max_health = value
	max_health_changed.emit(value)
	if health > max_health:
		health = max_health
		

	
func get_max_health()-> int:
	return max_health

func set_health(value: int):
	if value < health and immortality:
		return 
	
	print("value to change: ", value)
	print(get_tree_string_pretty())
	health = health+value
	print("value after change: ", health)
	if health > max_health:
		health = max_health
	elif health <0:
		health = 0
	
	print('current live after math: ', health)
	health_changed.emit(health)
	
	
func get_health()-> int:
	return max_health

HealthBar:

extends ProgressBar
var player
var player_health : Health
# Called when the node enters the scene tree for the first time.
func _ready() -> void:
	player =  get_tree().get_nodes_in_group("player")[0]
	player_health = player.get_health_node()
	max_value = player_health.get_max_health()
	value = player_health.get_health()
	player_health.health_changed.connect(health_changed.bind())
	player_health.max_health_changed.connect(max_health_changed.bind())


# Called every frame. 'delta' is the elapsed time since the previous frame.
func _process(delta: float) -> void:
	pass


func health_changed(new_health_value):
	print('current live: ', new_health_value)
	value = new_health_value

func max_health_changed(new_max_health):
	max_value = new_max_health

When i look at the Code in the Debugger, values are changed:


but in logging of the print statement there is always written the max health that are 10:

maybe somebody can help me im a bit confused.

P.S. _on_sceen_start() in Player will be called from the root node in its ready function. Health is a Childnode of Player, but should also work on an enemy.
Thanks alot for your help in advanced.

You mixed up your getter for health with max health, which I think is messing with what you’re seeing vs what you’re printing.

func get_health()-> int:
	return max_health

In general, your code is very confusing with all these getters that don’t do anything special. If you’re just returning the same value - why do you even need a getter? It’s harder to follow what’s actually going on.

1 Like

oh dear, thanks that was it. It should return health not max health. How would you work instate getters?

You don’t need a getter at all, just remove it altogether and leave only the setter, e.g.:

@export var max_health: int = 3: set = set_max_health
@onready var health: int = max_health: set = set_health

And then remove these functions:

get_health()
get_max_health()

This will not change the behavior in any way, only declutter your code for easier readability.

1 Like