Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

RigidBody2D not colliding properly with CollisionShape2D (set to one_way_collision: on) #27593

Closed
hiulit opened this issue Apr 2, 2019 · 6 comments

Comments

@hiulit
Copy link

hiulit commented Apr 2, 2019

Godot version:

Godot Engine 3.1.stable.official

OS/device including version:

macOs Mojave 10.14.3
Intel Iris Pro 1536 MB

Issue description:

I'm using GLES2.

Scene tree:

Node2D
├── TileMap
├── KinematicBody2D
├── RigidBodyBody2D
└── Node2D
    ├── StaticBody2D
    ├── StaticBody2D
    ├── etc

The TileMap has a tileset.tres Tile Set with a Single Tile with selected_collision_one_way set to on. If I turned if off it seems to work.

I've also tried using a bunch of StaticBody2D with CollisionShape2D and I get the same behaviour. When one_way_collision is on the RigidBodyBody2D doesn't collide properly. But when it's off it seems to work fine.

The RigidBodyBody2D is set to Mode: Rigid. If I change it to Mode: Character seems to work fine with either one_way_collision on and off.

rigidbody2d-collisions

Steps to reproduce:

Download the zip and try to play with the TileMap and the StaticBody2D changing one_way_collision to on/off. Also try playing with the RigidBodyBody2D modes.

Minimal reproduction project:

test-rigidbody2d-collisions-one-way.zip

UPDATE

Version with the body's center of mass fixed.

test-rigidbody2d-collisions-one-way-fixed-body-center-mass.zip

@Xrayez
Copy link
Contributor

Xrayez commented Apr 3, 2019

The rigid body's shape isn't aligned with body's center of mass, which may or may not be relevant to this issue, also see #12353.

@hiulit
Copy link
Author

hiulit commented Apr 3, 2019

Thanks for pointing this out @Xrayez . I changed the body's center mass and now the interaction with CollisionShape2D is better, but it still goes through it when it's set to one_way_collision.

The RigidBody2D are set to Rigid mode.

rigidbody2d-1

rigidbody2d-2

The left one goes through a TileMap that has a tileset.tres Tile Set with a Single Tile with selected_collision_one_way set to on.

The middle one stops on a StaticBody2D with a CollisionShape2D with one_way_collision set to off.

The right one stops on a StaticBody2D with a CollisionShape2D with one_way_collision set to on.

@hiulit
Copy link
Author

hiulit commented Apr 3, 2019

Here's another example to show that they go through with one_way_collision set to on.

rigidbody2d-3

@hiulit
Copy link
Author

hiulit commented Apr 9, 2019

Here's the test project with the fixed body's center of mass.

test-rigidbody2d-collisions-one-way-fixed-body-center-mass.zip

@warner-programming
Copy link

warner-programming commented Nov 3, 2019

I have the same issue:
https://giphy.com/gifs/godot-cMb9ViHmeLogq7v9Ts
It looks as if as soon as one of the contact points gets below the one way platform top, the rigidbody falls through. I can imagine that a solution would be to check the previous state of the object instead of the current one: if it came from above, it should collide.

Here is the source:
http://tiny.cc/6dtmfz

My workaround:
Here is a crude fix I made for my own project: http://tiny.cc/aawmfz
Maybe someone else finds it useful. The idea is this: a platform uses layer 17. That layer is ignored by all other bodies. The platform has an Area2D attached. When a body enters that area, and it is above the platform, collision bit 17 is set on the body. When the body leaves the area, the bit is cleared. It doesn't work perfectly, but it seems to be usable for my project.
Edit: Here is the final version of the script: https://pastebin.com/H4Uym0mK

[EDIT, much later]
For KinematicBodies I'm now using a basic move_and_collide() test to see if my KinematicBody2D will hit a platform before using move_and_slide. If it does, and the normal goes up, I enable the collision layer, else I disable it. The reason for doing this is to prevent my KinematicBody2D from tunnelling through platforms when the velocity is too high.
Here is the code:
if (force.y <= 0.0): set_collision_mask_bit(17, false) else: set_collision_mask_bit(17, true) var testHit = move_and_collide(force, false, false, true) set_collision_mask_bit(17, false) if (testHit != null): if (testHit.collider.get_collision_layer_bit(17)): if (testHit.normal.y < -0.5): set_collision_mask_bit(17, true) move_and_slide(force, up.rotated(rotation), false, 4, 0.785398, false)

@madmiraal
Copy link
Contributor

Fixed with #39880 and cherry-picked for 3.2.3.

@madmiraal madmiraal added this to the 3.2 milestone Oct 3, 2020
@akien-mga akien-mga modified the milestones: 3.2, 4.0 Oct 3, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging a pull request may close this issue.

6 participants