Floor is made up of tiles with their own box colliders. Pushable item gets stuck on the “seams”

Floor is made up of tiles with their own box colliders. Pushable item gets stuck on the “seams”

So I have a scene where the floor is made up of some tiled objects. All of these have the exact same height and exact same Y position. I also have a block with a rigidbody that you can push on the ground. It has a rigidbody with freeze rotation enabled for X, Y, and Z.
My issue is this: when pushing the block around, it sometimes gets stuck when reaching the seams of the tiled objects. I have tried giving it a friction of 0, but it still gets stuck sometimes. Is there any solution for this, other than manually creating a big collider that spans the entire floor?


Answer 1:

By far the most efficient solution is what you said: combine the tiles into a single collider. You can do this manually, or write a script to automatically merge adjacent colliders into bigger boxes. There are a few existing questions about this latter approach.

If that’s impractical for your case (say, tiles are created/destroyed/moving frequently) then the next best thing is to give your pushables a tiny bit of a radius. You can build a cubic cage of narrow capsule colliders, with box colliders inside. This means when you get a phantom collision with the seam, the curvature of the collision on your pushable will help it ramp up and over, instead of getting stuck. It’s more colliders that way, of course.

One last thing you can try, as suggested in the Bennett Foddy talk linked above, is add an extra collider right along the seam, to help catch the penetrating shape from below instead of edge-on.

Answer 2:

I recently had the exact same problem where it was entirely infeasible to combine colliders. Here is a fairly easy to implement and very effective solution:

Disable collision checking for edges that shouldn’t ever be hit. In your case, the edges between the should never actually be collided with, so why check them at all?

It should just be a couple extra checks on initializing the tiles (and on ticks, if they move) to see which edges are “collidable”, and then in your collision checker just ignore the unmarked edges