Help with signal calling

I am currently trying to make a tower defense game. very much a beginner. And I know there must be a better way for me to use signals in this setting. I am trying to cast a signal when the enemy gets to the end of the path, and then take damage. Calling get_parent twice seems so wrong here, but I can’t figure out how to connect the signal another way.

Thanks in advance!

game.gd

extends Node2D

var health = 20
signal end_of_path

func _on_end_of_path(enemy, damage): #connected signal
	print("signal emitted")
	health -= damage
	print(health)
	enemy.queue_free()

enemy.,gd

func _process(delta: float) -> void:
	const SPEED := 500.0
	progress += SPEED * delta
	if progress_ratio > 0.99:
		get_parent().get_parent().emit_signal("end_of_path", self, damage)
		print("Progress done")

root
|-Game
|—Camera
|—Path2D
|-----Spawned enemies
|–Timer
|–TileMap

Do like this:

var called = false

func _process(delta: float) -> void:
	const SPEED := 500.0
	progress += SPEED * delta
	if progress_ratio > 0.99 and !called: # means if called is false
		get_parent().get_parent().emit_signal("end_of_path", self, damage)
        called = true
		print("Progress done")

You could refactor it so that each enemy emits the signal.
Inside enemy.gd:

signal end_of_path(enemy, damage) 

func _process(delta: float) -> void:
	const SPEED := 500.0
	progress += SPEED * delta
	if progress_ratio > 0.99:
		end_of_path.emit(self, damage)
		print("Progress done")

Where you spawn the enemy you would connect the signal:
(pseudo code assuming you spawn inside game.gd) game.gd:

var enemies:Array[Enemy]

func spawn_enemy(): 
    var new_enemy = Enemy.new()  
    new_enemy.connect("end_of_path", _on_end_of_path)
    enemies.append(new_enemy)

And lastly modify the signal code to free the enemy:

func _on_end_of_path(enemy, damage): #connected signal
	print("signal emitted")
	health -= damage
	print(health)
    enemies.erase(enemy)
	enemy.queue_free()
1 Like

This works a lot better, thanks!