godot icon indicating copy to clipboard operation
godot copied to clipboard

Collision Detection between CharacterBody2D and RigidBody2D not working(properly)

Open Vukbo opened this issue 2 years ago • 5 comments

Godot version

v4.0.beta10.mono.official [d0398f62f]

System information

Windows 10 Home, Intel(R) Core(TM) i5-4210H CPU @ 2.90GHz 2.90 GHz,

Issue description

I want the Rigidbody2D to detect the Collision with the CharacterBody2D so I can program the behaviour of the RidiBody2D according to the Player.

The Issue:

https://user-images.githubusercontent.com/11051231/209828258-6e06fa64-1b3c-49a4-8c11-3fc1e777bda0.mp4

The RigidBody2D doesn't recognize the CharacterBody2D when he is on the ground and the CharacterBody2D is touching him from the side. (Example 01)

https://user-images.githubusercontent.com/11051231/209828325-540fd7a4-97f7-4bb8-a082-18ded349878c.mp4

The exception to this is when the RigidBody2D is falling on top of the CharacterBody2D, then he recognizes the collision. (Example 02)

Both bodies are on the same layer. RigidBody2D has max contacts > 0 and contact monitoring enabled. Still no collision between those. The collision between the StaticBody2D and the Rigidbody2D seems to work fine.

Steps to reproduce

Move the Player with Left and Right Arrow Keys and Space to Jump.

Expected Behaviour: When you move the Player into the standing RigidBody2D it should recognize its collision and print the name of the colliding node in the console.

Current Behaviour: Doesn't recognize the Player coming from the side, when standing. Seems to me that the RigidBody2D seems to be sleeping, yet can sleep is disabled.

Minimal reproduction project

CharacterBody2DCollisionIssueWithRigidBody2D.zip

Vukbo avatar Dec 28 '22 14:12 Vukbo

I think this is a bug that should be fixed, but fortunately you can detect the collision in CharacterController.cs in this case.

CharacterController.cs: line37~

MoveAndSlide();
KinematicCollision2D kc = GetLastSlideCollision();	// or use GetSlideCollisionCount() and GetSlideCollision(intdex)
if (kc != null)
{
	Node colliderNode = (Node)kc.GetCollider();
	GD.Print(colliderNode.Name);	// This will print "RigidBody" when the player collides with the RigidBody.
}

heppocogne avatar Dec 29 '22 00:12 heppocogne

Thanks for sharing the workaround. Do you know when this bug will be fixed?

Vukbo avatar Dec 29 '22 10:12 Vukbo

Please create a minimal reproduction project in GDScript instead of C# for two reasons:

  • Non-Mono builds of Godot are easier to set up and have less moving parts.
  • This rules out C# being the cause of the bug.

Calinou avatar Dec 29 '22 19:12 Calinou

As a work around, I added a new kinematic/Char body within the player, and it has its own collision layer, then I marked that collision layer on the ribigbody, so only the rigid bodies can detect this extra collider. I know it is not fancy, but it does the trick.

leon-fenzl avatar Mar 05 '23 14:03 leon-fenzl

The problem is with the CharacterBody2D (or CharacterBody3D).

The RigidBody2D vs RigidBody2D works perfectly in these situations. The problem is only with the CharacterBody2D vs RigidBody2D or CharacterBody2D vs CharacterBody2D. It gets worse if it involves a moving platform.

Blue boxes == RigidBody2D Red boxes == CharacterBody2D

https://user-images.githubusercontent.com/25422687/223070780-f283db82-c01b-4401-8e6d-7b65f55a7d1d.mp4

characterbody_physics_tests.zip

AttackButton avatar Mar 06 '23 09:03 AttackButton

As a work around, I added a new kinematic/Char body within the player, and it has its own collision layer, then I marked that collision layer on the ribigbody, so only the rigid bodies can detect this extra collider. I know it is not fancy, but it does the trick.

I will try that. I think the bug could be caused by the removing of the sync_to_physics from KinematicBody2d/CharacterBody2D since version 3.x.

AttackButton avatar Mar 29 '23 18:03 AttackButton

I'm having this exact issue in 4.0.2 using gdscript. This is the only place I've seen a clear presentation of the exact issue that I'm struggling with.

I tried the work around of adding another CharacterBody2D to my original CharacterBody2D, and putting it on it's own collision layer, but the RigidBody2D is still not registering collision with it when it's on the floor (or close to the floor) and when hit from the side. (I edited the comment. Rebuilt my game in Godot 3.5.2. The bug is not present there and everything is working fine)

KJSavinelli avatar May 17 '23 18:05 KJSavinelli

Figured I'd bring some other input from a slightly different use case: In Godot 4.0.3-stable I'm having the same issue where the CharacterBody2D does not move the RigidBody2D in a "Top-down" format.

For describing the video: I have a player that is a CharacterBody2D and the "shapes" are RigidBody2D's that have nothing changed in the inspector other than gravity set to 0.

Confirmed with another that it's not just my system. Same issue on Linux and Windows 10.

https://github.com/godotengine/godot/assets/95942443/b977ac0b-d29a-47c6-b857-60b898e611d5

WiseNoodle avatar Jun 05 '23 14:06 WiseNoodle

A current workaround is to disable the collision mask on the CharacterBody2D that matches the layer that the RigidBody2D is on.

WiseNoodle avatar Jul 12 '23 19:07 WiseNoodle

I'm experiencing this very issue on my project. It seems the bug has yet to be fixed? I'm using Godot v4.1.1.stable.official [bd6af8e0e]. In my case, the collision does trigger if the RigidBody2D falls on top of the CharacterBody2D, as previously mentioned.

yurixander avatar Sep 28 '23 01:09 yurixander

A current workaround is to disable the collision mask on the CharacterBody2D that matches the layer that the RigidBody2D is on.

This fixed my issue, thanks!

JuDelCo avatar Oct 10 '23 17:10 JuDelCo

I'll preface my comment by saying I am very new to Godot and Python (GDscript) but this seems to be the same issue I'm having and WiseNoodle seems to be correct. My player is a CharacterBody2D and the "Asteroids" are RigidBody2Ds

https://github.com/godotengine/godot/assets/148629354/6b205739-fd06-4ed3-8e47-4944dba8226d

Zoidster avatar Oct 21 '23 12:10 Zoidster

A current workaround is to disable the collision mask on the CharacterBody2D that matches the layer that the RigidBody2D is on.

This does fix the problem, but leads to another one: Imagine if a CharacterBody2D pushes a RigidBody2D and pushes it to a place where the rigid is against a wall, the rigid will behave weirdly. I have tested this and it proved to be true.

Lazy-Rabbit-2001 avatar Jan 17 '24 11:01 Lazy-Rabbit-2001

Exactly, the proposed workaround makes it likely that your CharacterBody2D will push any RigidBody2Ds into/through walls, floors, etc.

hunterloftis avatar May 12 '24 00:05 hunterloftis

I have the same issue, but my RigidBody2D falls from above on the CharacterBody2D. Sometimes it triggers the collision and sometimes it's not. The big box is colliding, but a small debrees is not, it pushes my player into the ground and I cannot apply force to the RigidBody because I have no collision despite having it pushing me into the ground

image

        int count = GetSlideCollisionCount();
        for (int i = 0; i < count; i++) {
            KinematicCollision2D c = GetSlideCollision(i);
            if (c.GetCollider() is RigidBody2D) {
                RigidBody2D body = c.GetCollider() as RigidBody2D;
                GD.Print(">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>COLLIDED! " + body.Name);
                body.ApplyCentralImpulse(-c.GetNormal() * push_force);
            }
        }

I never detect the collision here.

codemeow avatar Jun 24 '24 18:06 codemeow

I'm also not seeing collisions between a stationary staticbody2D and a characterbody2D. My workaround is setting up the collision check within the characterbody2D script.

andrew-suh avatar Jul 17 '24 03:07 andrew-suh

Just a heads-up, this also happens with StaticBody2D

vvvvvvitor avatar Jul 31 '24 00:07 vvvvvvitor

A current workaround is to disable the collision mask on the CharacterBody2D that matches the layer that the RigidBody2D is on.

A better workaround is to set recovery_as_collision to true.

vvvvvvitor avatar Jul 31 '24 00:07 vvvvvvitor