Search Unity

Bug #1295857: MeshColliders causing OnCollisionEnter despite not making contact with the object

Discussion in 'Physics' started by dgoyette, Nov 28, 2020.

  1. dgoyette

    dgoyette

    Joined:
    Jul 1, 2016
    Posts:
    4,196
    Edit: Reported the bug. See reply below.

    I can't say for sure if this started happening only recently (Unity 2019.4 LTS), but I started noticing some odd behavior related to how collisions are being handled with one of my game objects. Specifically, OnCollisionEnter events are being fired even when two objects do not appear to be overlapping/contacting.

    In trying to narrow this down, it seems the issue is mostly/only noticeable when using mesh colliders that are much longer in one dimension than in the other two. This makes me wonder if it's some weird bounding box problem.

    To show an example of what I'm seeing, I have a game object in my game that vaporizes/destroys objects when they touch it. I was noticing some objects were being destroyed without actually touching it. So I started doing some testing. To keep it simple, the pink object you see here is the thing that is testing for OnCollisionEnter. It's a completely standard Unity primitive cube, default scale of (1,1,1) on the default collision layer, and a BoxCollider. I've placed it here so that its top surface is 0.25m lower than the floor you see to its left.

    upload_2020-11-28_12-3-15.png

    In my OnCollisionEnter code, for testing purposes, I'm creating a small sphere at the collision.contacts[0] position, so I can judge where the colliders are occurring. I then let a bunch of glass shards move past this object, being pulled to the right by some Rigidbody.AddForce calls.

    So now here are the collision points where all these little glass shards claimed to contact the cube:

    upload_2020-11-28_12-8-33.png

    Hopefully you can tell that almost none of them are touching the cube. I can even move that cube down another meter, and I still get these weird phantom collisions.

    If I replace the glass shards with more uniform objects, like spheres or cubes, I'm not seeing any problems. So I tested this with a single ProBuilder object, which I made into an awkwardly long, thin stick that cuts across the diagonal of a very large bounding box. As this object passes above the vaporizing object, at no point does it get with 0.25 meters of it, but the collision still triggers. In this next screenshot, the collision.contacts[0] point is where the 3D cursor is. Basically, directly on the surface of the PB object, but not even close to touching the cube.

    upload_2020-11-28_12-13-15.png

    This seems to be a mesh collider issue, not a PB issue, since this is happening with other mesh colliders. I notice it very dramatically when using long, thin mesh colliders like these broken glass shards:

    upload_2020-11-28_12-16-15.png

    So, the questions are: Is this a known issue? Is this a bug to report? Is there just something I'm potentially doing wrong? Is there something else I should do to diagnose the root cause?
     
    Last edited: Nov 28, 2020
  2. dgoyette

    dgoyette

    Joined:
    Jul 1, 2016
    Posts:
    4,196
    This was pretty easy to reproduce in a simple test project. I've reported bug #1295857 with a test case. The test just has a long, skinny ProBuilder object slide down a ramp. Near the bottom of the ramp is a cube with an OnCollisionEnter script on it. That script is triggering OnCollisionEnter even though the other object is still quite far away from it.

    Here you can see the long object sliding off the end of the ramp. It's on this frame it causes OnCollisionEnter with the small cube below it, even though there's quite a large distance between them. The object highlighted in orange is the collision.contacts[0].point, which is clear not touching the cube at all.

    upload_2020-11-28_13-2-8.png
     
  3. dgoyette

    dgoyette

    Joined:
    Jul 1, 2016
    Posts:
    4,196
    I was told by Unity QA that not only is this already known, it's actually by design:

    "This behavior is by design. Speculative (=predictive) collision detection can detect false positives because of the nature of how it works -- inflating the contact offset and using normal contact generation to discover contacts."

    So I guess that's all there is to it. It was deeply surprising just how "inflated" it seems the contact distance is allowed to get. I was getting "false positives" when the two objects at least a meter apart. But maybe it works better for some geometries than others.
     
  4. Edy

    Edy

    Joined:
    Jun 3, 2010
    Posts:
    2,510
    Have you tried reducing setting Collider.contactOffset to a small value? For example, in some cases I improved the contact generation by setting it to 0.001.
     
  5. dgoyette

    dgoyette

    Joined:
    Jul 1, 2016
    Posts:
    4,196
    I just tried that out. The default seems to be 0.01, and setting it to 0.001 doesn't seem to make a difference one way or the other.

    I still wonder if this really is expected behavior. The distances just seem so far to me. Here's an example of a window that just broke into 100 pieces, which get pulled towards that purple thing in the background via AddForce calls. The selected glass shard claims to have come into contact with that blue surface beneath it, which is 0.25 meters below it. Since becoming active, that glass shard collider has moved maybe 0.001 meters from its original position, and rotated maybe one degree as it "falls" towards the purple thing.

    upload_2020-12-2_14-47-40.png

    Or maybe continuous speculative really just isn't idea for long, thin things, like shards of glass.