OnCollisionEnter being called without the colliders actually colliding

Hi,

I’m having an issue with OnCollisionEnter being called without the colliders actually colliding, i.e. it’s like a bigger collider than defined for the objects. The physics however work when they should - when my club visually hit my ball it starts moving. It’s just that there’s like an area around the ball or club where OnCollisionEnter is called independent if the club actually collide with the ball or not.

In my code below I make the head of the club black to see when it OnColliderEnter is called.

void OnCollisionEnter(Collision coll){
	if (coll.gameObject.CompareTag ("Ball")) {

		Material headMaterial = GameObject.Find ("Head").GetComponent<Renderer> ().material;
		headMaterial.color = Color.black;

		}
}

There was another question about this with no answer which illustrates the situation:

Any ideas?

The answer given at:

OnCollisionEnter is called before the actual collision - Questions & Answers - Unity Discussions

explains the situation exactly, perfectly, and without error.

Your game code cycles and renders (draws), and the two are not in sync. In fact, your game can cycle several times before a frame is drawn. The Update() callback is called once before each frame is going to be drawn. However, FixedUpdate() is called when the code reaches the end of its cycle and starts up anew. OnTriggerEnter() is called during Update(). OnCollisionEnter() is called during FixedUpdate(). This is why your game ‘looks’ like nothing is touching when OnCollisionEnter() is called. Because the game collided them between the drawing of frames.

The biggest issue isn’t on your end. Unity should rename the OnCollisionEnter() callback because everyone thinks that where you put collider logic. You shouldn’t. FixedUpdate(), Rigid-Bodies, and OnCollisionEnter() are very intense (because they are processed several times between drawing frames to increase accuracy) and should be used sparingly. Except in your case where realistic objects need to behave as if they CAN NEVER OVERLAP IN THE GAME WORLD FOR ANY REASON because they are supposed to be solid, not-penetrable objects.

If you want the ball to not move until the game draws then use OnTriggerEnter() at small scales, and at larger scales, use OnColliderEnter().


TL;DR: The game is predicting they are going to touch before the screen is drawn again, and makes sure they start ‘colliding’ before it draws another frame, so they are not drawn overlapping.