Collision detection happens way too early.

Hello!

The concrete case:
I have multiple game objects with convex mesh colliders and rigid bodies that are not moving.
Those are being instantiated over and over again next to each other.

The goal:
I am using the convex mesh colliders and the rigid bodies to check if there is space for the game object after instantiation.

The idea is that when a collision occurs - then there is no space and the game object should be destroyed. If not - then the game object remains.

The problem:
OnCollisionEnter is called even when the colliders are not touching, but are somewhat close to each other.

Check this image.

The execution:
I attach a script on the game objects with the colliders that is to detect collisions.

public class RoomCollider : MonoBehaviour {
    public bool IsSpace { get; private set; } = true;

    void Start()
    {
        IsSpace = true;  
    }

    void OnCollisionEnter(Collision collision)
    {
        IsSpace = false;
    }
}

An object is instantiated, the convex mesh colliders and the rigid body are added.

// A collider is instantiated based on a game object with multiple mesh colliders.
GameObject generationCollider = Instantiate(collider, room.transform);

// It is then scaled down a little.
float scaleDown = 0.95f;
generationCollider.transform.localScale *= scaleDown;

// A rigid body is then added.
Rigidbody rigidbody = room.AddComponent<Rigidbody>();
rigidbody.useGravity = false;
rigidbody.constraints = RigidbodyConstraints.FreezeAll;
rigidbody.useGravity = false;

// The mesh colliders are marked convex.
MeshCollider[] generationMeshColliders = generationCollider.GetComponentsInChildren<MeshCollider>();
foreach (MeshCollider meshCollider in generationMeshColliders)
    meshCollider.convex = true;

The script waits for the FixedUpdate execution and then checks if a collision has occurred trough the “IsSpace” property.

What I have tried (and found on the forums):
Potential cause: Usually small scaled objects produce such behaviour
My case: My objects are scaled upwards and not downwards, but I played with scales and this shouldn’t be the case.

Potential cause: Unity predicts collision based on movement.
My case: My objects don’t move.

Sorry if this is a dumb question, but I don’t see how the collision event can be firing without the objects overlapping. So, are either of these possible?

  • The object is starting out at one place, and you move it to a new place after instantiation, but it still triggers collision based on its initial position? (Confirm this by logging the objects’ position in OnCollisionEnter to make sure it’s occurring when the object is where you think it should be.)
  • Are you sure that the OnCollisionEnter is firing because of these two colliders, and that it isn’t another collider triggering the collision with one of the objects?

Again, sorry if this isn’t helpful, but that does seem like bizarre behavior if collision is occurring before the objects actually overlap…

I just verified that the collisions are happening between the correct colliders and at the correct positions.

Offtopic: Gravia seems pretty cool.

Any chance it’s the same issue as this guy?

Doesn’t seem to be the case, but I played around and found the following:

Using box colliders instead of convex mesh colliders seems to not reproduce the problem, so this is the workaround that I am using now.

Thank you for your answers!

Incase someone has similar issues I think what solved it for me, after you mentioned the issue didnt occur with box colliders, was switching the cooking options that go along with the mesh collider to none. If it is still colliding without touching it’s more descrete than with the cooking options on.

Just found out, there is the collision offset variable. By default (or at least in my Unity Project) it was set to 0.1. Set it to close to zero and it fixed my issues.

To change the collision offset, go to:
Edit > Project Settings > Physics > Default Contact Offset

Again, set it close to zero.

It’s non-zero for a reason. You should try to understand what it’s for before changing this but in the end, it’s up to you.

Also, please don’t necropost.