Enemies spawn and despawn based on health

Godot Version

4

Question

Basically in my game the healthbar acts as an insanity meter so if you lose 25 health you’re in insanity level 1. So what I’m saying is when the player reaches 50% health, they go into insanity level 2. I want the insanity level 1 enemies to despawn and level 2s enemies to spawn and vice versa when healed. Is that too much? Thanks in advance.

Groups are your friend! Have some enemies in “instanity_1” group, others in “instanity_2” group and so on. Then once the player health crosses a certain threshold, get all nodes in a group and destroy them:

# When player health goes below 50%
var current_insanity = "insanity_1"
for enemy in get_tree().get_nodes_in_group(current_insanity):
    enemy.free()

current_insanity = "insanity_2"

Something like that

1 Like

Can you explain a bit more? I’m really new so I’m not really able to fully understand RN

Sure. Well, there are two approaches that you can take with this:

  1. Enemy watches player health and when they transition into a new insanity level, the enemy despawns itself.
  2. The player (or a singleton in the world or something) watches the player health. And when it transitions into a new insanity level, it finds all the enemies from the previous insanity level and despawns them.

You could go either route. I’m going to describe the second one, that’s the way I would do it.


So you have the player. He has hp and the current insanity level.

var hp: int = 100
var current_insanity: int = 0

Now every time the player health changes, you check if the insanity level is still the same. You can do that with a setter in GDScript:

var hp: int = 100:
    set(value):
        hp = value
        check_insanity()

This check_insanity method now gets triggered every time the health changes. Either when taking damage or healing. In it, you want to evaluate what the new insanity should be.

func check_insanity() -> void:
    var new_insanity = current_insanity
    if hp <= 25:
        new_insanity = 3
    elif hp <= 50:
        new_insanity = 2
    elif hp <= 75:
        new_insanity = 1
    else:
        new_insanity = 0

    # check if the insanity changed
    if new_insanity != current_insanity:
        respawn_enemies()
        current_insanity = new_insanity

Now for the part you were originally asking. How to despawn all the enemies? If the new insanity is 1, you want to despawn all the enemies that belong to insanity 0. You can do that with the Groups functionality that I mentioned.

func respawn_enemies() -> void:
    var enemy_group_label = "insanity_" + str(current_insanity)
    var enemies = get_tree().get_nodes_in_group(enemy_group_label):
    for e in enemies:
        e.queue_free()

And now you can set your enemy spawner to start spawning a new type of enemies for the new level of insanity you are on.

I hope this makes more sense.

Thanks alot man!! This is what I wanted!

1 Like