Area2D has trouble detecting player when its collisionShape changes

Godot Version

4.2-stable

Question

Hello. I’m new at Godot and I’ve been learning GDScript for a couple of weeks now. My issue is the next one:

I’ve set an Area2D to an NPC to detect the player. It works as follows:
pseudo-code

_on_area2D_body_entered(body):
if not body is Player: return
aux = body

_on_area2D_body_exited(body):
if not body is Player: return
aux = null

This set up is easy. Long story short: it detects when the specifically the player is inside the area. If any other object which is not the player enters the area it gets ignored, but if the player enters (Class_name Player), it saves its data into an auxiliary variable.
Then, the NPC has a state machine in the “_process(delta)” function. It has several states, but the important ones are IDLE and SIDE. The second one is active when the player is inside the Area2D (if aux == body → True == it has player info inside, then the player is inside the Area2D).

The problem is that the player can, for example, crouch (done with AnimationPlayer) and doing so makes the NPC’s Area2D detect that the player has gone out an in the area. I’ve got to the conclusion that it’s because of the Player’s collisionShape changing its shape and this causes the NPC to go to IDLE for a couple of frames, since the player is not nearby. I’m attaching one video to show it.

About the Player’s AnimationPlayer, when crouching it changes the shape of the collisionShape to make it smaller (round shape), and when you stop pressing Ctrl, the player stands up making the collisionShape go into a pill shape again.

Is this a wrong approach? Should I do any extra steps to ensure that the state machine is more robust? Or is there anything that I’m missing about the detection?

Note: This is my first post here, so I don’t really know how to format the code and question. If you have any suggestion I’ll edit it with pleasure.

Technically, you can’t change a CollisionShape, so what is happening is it’s getting replaced by a new one. This triggers the exit notification. You have two options. Either have both shapes at once and just switch which one is active, which is cleaner anyway, or use hysteresis (aka a timer) to delay the detection on the NPC.

1 Like

As update, I’ve tried adding 2 CollisionShapes to the player and enabling/disabling depending on the user’s state (crouching enables an little circle collisionShape and disables a bigger capsule collisionShape and not crouching vice versa), but the issue is still there.
The Area2D of the different objects and NPCs detects that the player disappears and reappears for about 3 frames (area2D_body_exited triggers → aux = null, then area2D_body_entered triggers again → aux = playerData), thus changing their states.
To fix it I implemented the hysteresis you mentioned to force the program to wait a couple miliseconds before allowing any state change.

Thank you a lot :slight_smile:

1 Like

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