• 2D
  • How to get Area2D to instantly emit area_entered signal when entering another Area2D?

I'm new to the engine (but not programming in general) and am using it to prototype a fighting game. I'm running into an issue with detecting when an attack's hitbox connects with the enemy's hurtbox. Both hitbox and hurtbox are an Area2D with a child CollisionShape2D using shape RectangleShape2D. The issue is that there appears to be a delay before the hitbox emits the area_entered signal: if the hitbox is active for only 1 frame (at 60 FPS), the signal is never emitted, and at 2 frames it is only rarely emitted.

I have an AnimationPlayer which toggles the attack's hitbox on and off by flipping the disabled property of the hitbox's CollisionShape2D. If the attack is active for 1 frame, the area_entered signal is never issued. The AnimationPlayer setup for 1 active frame looks like this (hitbox active on frame 6 and disabled on frame 7):

If the attack is active for 2 frames, the area_entered signal is issued, but inconsistently. There are significantly more misses than hits. The AnimationPlayer setup looks like this (hitbox active on frame 6 and disabled on frame 8):

If the attack is active for 3 frames, it emits the area_entered consistently as expected. The AnimationPlayer setup looks like this (hitbox active on frame 6 and disabled on frame 9):

I've got Visible Collision Shapes enabled in the debug menu and I can see that the areas are indeed active and overlapping even at 1 active frame, so I'm not sure why it isn't emitting the signal. My only guess is that Godot's physics processing somehow requires areas to overlap for a period of time before emitting the signal? But I have no idea if that's actually true, and figured I would ask here before resorting to trolling through the engine code myself. Engine version is 3.4.2. Any guidance on what I can do to get signals emitted consistently at 1 active frame (or an alternative method of detecting area overlaps) would be appreciated.

Your code should be on physics_process(). If it is in process() it will be unsynced with the physics engine causing weird frame issues (multiple hits on one frame or none, etc.). You also have to enable sync to physics on the animations. There should be a check box on the right side of the animation player to sync to physics. I think that should fix it.

I'm already using physics_process() instead of process(), but I think that's unrelated to this since signal handling functions are in neither of those functions. Should I be checking for area overlaps in _physics_process() somehow instead of using signals?

I'm also not seeing a way to sync the AnimationPlayer to physics (in editor or on google) - only the KinematicBody2D, but checking that exhibits the same behavior.