Signal emitting multiple times

Godot Version

Godot 4.3

Question

To keep a kill score in my game I have my goblin enemie emit a signal whenever he dies. This signal is emitted to an autoplay EventBus and then used in my world scene to increase the score. However when a goblin dies the signal is emitted multiple times making the function to increase the score run multiple times.

EventBus

signal dead(points)

Goblin enemy

func take_damage():
	hit.play("hit")
	hp -= 1
	if hp == 0:
		queue_free()
		EventBus.emit_signal("dead", 1)
		const blood_splatter = preload("res://Utility/blood.tscn")
		var blood = blood_splatter.instantiate()
		get_parent().add_child(blood)
		blood.global_position = global_position

World

@export var wave: Array[Wave_Info] = []

var time = 0
var score = 0

func _ready():
	EventBus.dead.connect(increase_counter)
	
func _on_timer_timeout() -> void:
	%PathFollow2D.progress_ratio = randf()
	time += 1
	var enemy_spawns = wave
	for i in enemy_spawns:
		if time >= i.time_start and time <= i.time_end:
			if i.spawn_delay_counter < i.enemy_spawn_delay:
				i.spawn_delay_counter += 1
			else:
				i.spawn_delay_counter = 0
				var new_enemy = load(str(i.goblin.resource_path))
				var counter = 0
				while counter <= i.goblin_num:
					var enemy_spawn = new_enemy.instantiate()
					enemy_spawn.global_position = %PathFollow2D.global_position
					add_child(enemy_spawn)
					counter += 1

func increase_counter(points):
	score += points
	print(score)

My guess is that it has something to do with the fact that there are multiple enemys on screen so the signal is emitted for all of them but i have no clue how i would fix that.

Hello, @worthdwarf! Maybe you attack two goblins in each other at the same time?

while counter <= i.goblin_num:
     # Spawn goblins while counter <= i.goblin_num
     # So, if i.goblin_num = 2, this code spawns two goblins almost simultaneously

Ok, I think it’s true:

Try to make dead signal at Goblin enemy script and emit from it. And connect your increase_counter function with dead signal of each emeny_spawn instances.

I changed the script so only one enemy spawns every second. Now the increase_counter function is executed exactly 2 times for every enemy death.

Enemy spawn

func _on_timer_timeout() -> void:
	%PathFollow2D.progress_ratio = randf()
	time += 1
	var enemy_spawns = wave #wave is the array with the wave information
	for i in enemy_spawns:
		if time >= i.time_start and time <= i.time_end:
			if i.spawn_delay_counter < i.enemy_spawn_delay:
				i.spawn_delay_counter += 1
			else:
				i.spawn_delay_counter = 0
				var new_enemy = load(str(i.goblin.resource_path))
				var enemy_spawn = new_enemy.instantiate()
				enemy_spawn.global_position = %PathFollow2D.global_position
				add_child(enemy_spawn)

Try this also.

Your <= while loop will run twice if i.goblin_num is one. You are probably spawning two enemies.

  • 0 <= 1 is true
  • 1 <= 1 is true because 1 == 1
  • 2 <= 1 is false, spawning ends.

Try using < less than, not equal to.

1 Like

this had indeed fixed the issue many thanks!

1 Like

This topic was automatically closed 30 days after the last reply. New replies are no longer allowed.