Area2D body_entered not triggering

Godot Version

v4.3.stable.official [77dcf97d8]

Question

Hello, I’m new to Godot but experienced with programming. I just finished the Your First 2D Game tutorial, and collisions were working fine. I tried to do all the same things in my own project, and there, the _on_body_entered handler is never called. I can’t figure out what the difference is, and none of the search results I could find apply to me. Please help, what dumb thing am I missing?

I don’t have a public git repo for this, is there a standard way to share it as a zip?

Some info about the project, and things I checked based on other search results:

  • I have no error messages.
  • My Player is an Area2D node, and my Enemy is a RigidBody2D node.
  • Main is the default scene for the project and is a basic Node type node.
  • The Enemy and Player are both static child nodes of the Main scene, but I also tried dynamically spawning one in the Main _ready() and that didn’t collide either.
  • The Player and Enemy do not start overlapped.
  • The script shows the green arrow next to _on_body_entered and clicking it shows the expected body_entered signal:
  • My _on_body_entered has no conditional logic yet.
func _on_body_entered(body: Node2D) -> void:
    print("Body entered player: " + body.name)
    handle_hit()

func handle_hit() -> void:
    $CollisionShape2D.set_deferred("disabled", true)
    is_flashing = true
    $AnimatedSprite2D.visible = false
    $InvincibilityTimer.start(hit_invincibility_duration)
    $FlashTimer.start(hit_flash_duration)
  • Both Player and Enemy have CollisionShape2D. Both use a CapsuleShape2D. Neither have been scaled, but the one for Enemy has been rotated. Removing the rotation has no effect.
  • Enabling Visible Collision Shapes shows them positioned as expected, enabled (collision shape is blue), and overlapping.
  • Player has collision layer 1 and mask 1, Enemy has collision layer 1 and no mask. Giving Enemy mask 1 has no effect. Player mask 2 and Enemy layer 2 also has no effect.
  • Player has Monitoring on.
  • Enabling Contact Monitor and setting Max Contacts Reported to 1 on Enemy had no effect. I’m guessing these apply to the signals for things entering the Enemy rather than the Enemy entering things?
  • I tried connecting the signal in code in Player _ready() instead of the editor but that didn’t make a difference. (Connecting it in both editor and code showed a runtime error as expected.)
  • An unrelated custom signal emitted by Player is being successfully handled by the Main script.
  • If I call handle_hit() directly in Player _ready(), the flashing and disabled collisions happen as expected (collision shape turns white). The timer events properly stop the flashing and theoretically turn collisions back on (shape turns blue again).
  • The signal doesn’t fire when the CollisionShape2D is disabled either, so I’m not just working with it backwards.
  • I have no control nodes in this project.

What you can do is upload on google drive and put the link here, and probably this will be necessary because you said that already did all the checking.

1 Like

The problem here is how you’re moving your enemy, RigidBody2D can’t be moved directly as you’re doing, look in the docs:


For the way you want to move you should use CharacterBody2D instead. Also, you NEVER move your character in the _process callback, always do the physics related code in the _physics_process.

1 Like

Thank you so much!