How to resend an area entered signal?

Godot Version

Godot-4

Question

I have multiple creatures interacting using area_entered and area_exited signals. Things work fine until hitting this scenario:

  1. One creature enters the area of another, both emit signals to each other and theirs stats trigger them to attack each other (fine).
  2. A third creature enters the areas of the other two and they recognize this new creature as a friend, so they are no longer in attack mode while their attention is on their friend (also fine).
  3. The third creature then leaves, and at this point, I want the first two creatures to return to attack mode. I envisaged that because the two creatures were still in each others areas, the signal would trigger again and they would attack each other, but obviously it doesn’t work that way. They’d first have to exit and then re-enter to retrigger. But I don’t want them to have to separate first.

Is there a simple way to invoke the signal again or do I need to resort to some other means of triggering the ‘attack’ function?

1 Like

So couple is fighting in the kitchen when their child walks in and they stop. The child turns around and leaves, so they continue to fight. .

Why not have the child trigger a resume fight signal upon kitchen exit. Probably a flag setting should be enough.

1 Like

Thanks (I like parent/child analogy btw). That would sound like a reasonable solution, except that it’s not quite as simple as returning to the fight. The fighting is based on checking each others’ stats, which is based on them entering each others’ detection area, but they never left it and their stats were altered because of their reaction to the child. I suppose I could store the original details and then overwrite the changes with the stored details when the child exits their area, but that seems a bit excessive.

I am wondering if the kid’s exit triggers mum and dad’s detection area collisions to be disabled, and then, have them reenabled in the next frame if it detects them being off? Would disabling and reenabling trigger their signals again?

What I normally do is make a seperate copy project and then try different things. Signals flying around can be confusing, so setup lots of print statements to trace flow.

Each creature could keep track of all the other creatures that are in its area - for example, it could keep a list that it updates whenever something enters or exits. Then, whenever the list updates, it can make a new decision about what mode to be in. Because it has a list of references to all the nearby creatures, it can always check what they are (friends, enemies, whatever), and thus choose whether to call the attack function.

You can on area exit, go through all overlapping bodies and call the attack function directly, though you will probably get repeated calls A → B and B → A if that makes sense.

func _on_attack_zone_exited(body: Node3D) -> void:
    stop_attacking(body)

    for other in $AttackZone.get_overlapping_bodies():
        if other is Creature:
            other.attack_check(self)

Thanks all. Good advice about duplicating the project and the print statements. It’s the print statements that helped me discover what the problem was.
Looks like I have a couple of different solutions I can experiment with there. I’m already using an array for creatures to follow a trail of food items, so I guess not much of an extra stretch to expand that array to include other creatures.
And yes, gertkeno, that does make sense; I don’t mind the A → B, B → A triggers. It seems in way or another I’m going to have to cycle through the actors. I’ll have a play around and see what ends up working.
Thanks all!