_on_stats_no_health() will be called by a signal when health <=0
If that signal is received by all bat-scenes, that would explain why killing one bat scene kills all the others as well. The code you provided does not show how you connect the signal, but why don't you simply call
func _on_Hurtbox_body_shape_entered(body_id, body, body_shape, area_shape):
stats.health -= 1
This would ensure it's only called in the instance with zero health-points.
the spawner(1) is supposed to spawn another bat once it dies!
Though that will only happen the first time, because you're increasing
spawnvalue by the passed argument. So calling
spawner(1) will emit the "spawn"-signal once, calling
spanwer(1) once more will emit the "spawn"-signal twice and so on. Furthermore I assumme you connected the "spawn"-signal to
spawnenemy, in which case you would spawn not just on but fourty (!) bats for each signal that is emitted!
On a sidenote: There's no need to use
RandomNumberGenerator here, you can use
rand_range instead of
RandomNumberGenerator.randf_range. Also you don't need to call
randomize() each time you generate a random number - doing it once (usually in
_ready) is enough. In programming random numbers are an illusion and actually depend on what's called a "seed" - if you know the seed and the algorithm, you can generate exactly the same sequence of "random" numbers over and over again. This is why you usually want to call
randomize() to change the seed everytime your code is run. You can choose not to, but then the numbers will be the same each time.
Yes i connected it to the bat node
Then the line
var player =$Bat is wrong! The bat-node in your image does not have any children at all, let alone one called "Bat". Either way you should really migrate your code for spawning new enemies away from a specific instance. Otherwise the code cannot be run anymore once that instance is freed - as mentioned above.