- Home /
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: http://answers.unity3d.com/questions/1067291/oncollisionenter-is-called-before-the-actual-colli.html
Any ideas?
Are you sure that there's only one object with the tag "Ball" on it?
Can you post a screenshot or video of the problem?
It's in VR so I need som help to do that so can't do that today. Howver the link: http://answers.unity3d.com/questions/1067291/oncollisionenter-is-called-before-the-actual-colli.html illustrates the same issue. You can see that before the collision the OnCollisionEnter is called.
There's an answer in the post you linked that's probably correct.
Collisions happens in the fixed timestep. Unity has probably calculated that the collision's going to happen, and has called the method.
What's your interpolation settings? If you have "none", your transform is going to jump a step forward on every physics frame, ins$$anonymous$$d of moving smoothly from one to the next. Try to set it to Extrapolate, and see if that helps. Also make sure that your Collision Detection is set to continuous dynamic.
Apparently my phone didn't send the reply.
I'm using continuous dynamic and tried extrapolate but no difference.
I'm a noob so I'm not sure but I don't think it has to do with the fixed time step. As with the example in the link I can moce the club in and out of the detection area very very slowly so it won't do any kind of guessing that a collision will happen.
Hmm, is any of your objects scaled strangely? With negative scale or something?
Also, what kind of colliders are you using? If you're using mesh colliders, I'd try setting them to convex, or replace them with (compound) primitive colliders.
Unsure if this is related, but I heard at some point that colliders are slightly larger than their actual scale. I think it's an editable Physics thing.
I couldn't find anything like that while googling =/ but to me it would make sense since it is very small objects.
Answer by ninja_gear · May 25, 2016 at 02:54 PM
The answer given at:
http://answers.unity3d.com/questions/1067291/oncollisionenter-is-called-before-the-actual-colli.html
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.
Thank you for your reply. I believe your explanation is correct and sorry if I'm stupid but I have problems with it since I can e.g. move the club in a direction that it will not hit the ball but go past it. Still it gives an alert when it comes within a certain distance that it has become a collision.
I however understand your explaination enough to move away from OnCollisionEnter() and ins$$anonymous$$d have made a child to the ball that is atrigger ins$$anonymous$$d (if I make the ball a trigger it will to work well with the physics I assume) and play around to make that work ins$$anonymous$$d.
Your answer
Follow this Question
Related Questions
Collision detection when no collision happens,OnCollision is called without a collision 1 Answer
How to detect if target is inside an "arc" area? 0 Answers
my thing keeps going through walls, but ridged bodies can touch the collider 0 Answers
How to make objects collide once 1 Answer
How to detect correct collision from multiple game objects? Separate collisions 0 Answers