Area2D does not detect collisions

Godot Version

4.2.2.stable

Code

The entire code and assets are public here: GitHub - lukasgabriel/cats-dodge-dogs-2: Godot implementation of nieleyla/cats-dodge-dogs
It should work on your end if you clone it and import it, let me know if not.

Problem

I have two Area2D objects (Cat and Dog) with CollisionPolygon2D nodes as children.

As the player sprite changes, I update its polygon with $CollisionPolygon2D.set_polygon() to produce “pixel-perfect” hitboxes. Those polygons are pre-generated upon instantiation of the respective Node, using my HitboxFromSprite class. When I enable Visible Collision Shapes, those hitboxes are drawn exactly as I want them.

As you can see in cat.gd, it should print Hit! when there is a collision/overlap between the Cat and Dog. But no matter what I try, the _on_body_entered is never invoked, and nothing is printed to the console.

Here is a GIF to illustrate what happens:

Any help and tips are greatly appreciated! :gift_heart:
It should be noted that I am a total Godot beginner. If I am taking the wrong approach to this issue, feel free to suggest a better way of handling hitboxes/collisions. The only thing I want to avoid is hand-drawing them, as I plan on adding more sprites for different enemies and player characters later.

If someone would be open to it, I’d gladly hop on a Discord call with them to look at this together, and document the solution here if we find one.

I downloaded your project and took a look, your code have two problems:

1: Your characters are an Area2D but you connected the body_entered signal so your signal would never be triggered like that.

body_entered ( Node2D body )

Emitted when the received body enters this area. body can be a PhysicsBody2D or a TileMap. TileMaps are detected if their TileSet has collision shapes configured. Requires monitoring to be set to true.


This is the correct signal that u need to use:

area_entered ( Area2D area )

Emitted when the received area enters this area. Requires monitoring to be set to true.



2: You’re changing your collision shape in the wrong time, you’re using the _process callback for that, but this is totally wrong, everything physics related should ALWAYS be called inside _physics_process callback.


So apply this changes and your code will work properly

3 Likes

Thanks a lot!
After implementing those changes, the collisions are indeed detected just as I want them to. :smile_cat: