- Home /
Why is the relativeVelocity of a Collision always zero in OnCollisionEnter and OnCollisionStay?
I am colliding a GameObject (with a rididBody and a capsuleCollider on it) with a static mesh collider (the game world).
The relativeVelocity member of the Collision parameter in OnCollisionEnter and OnCollisionStay always has a magnitude of zero.
Surely it's impossible for objects to collide if they have no relative velocity?
I've just partly answered my own question - it looks like a bug.
The RigidBody has all the constraints set - it's position and rotation are both frozen in X, Y, and Z. It's position is deter$$anonymous$$ed by the hierarchy of GameObjects it is parented by.
If I remove the constraints, I get a valid relativeVelocity.
However, my original point still stands. Just because I am constraining the object doesn't mean that the collision between 2 objects doesn't have a relative velocity.
How do I request a fix for this problem in Unity?
Answer by Owen-Reynolds · Sep 18, 2013 at 04:03 PM
The physics system does a great job of bouncing around balls and cubes, but, IMHO, anything more complex is known to take a lot of care and feeding.
Take a look at the "compound collider" system. One trick is to have OnCollision only on the parent -- all child subcolliders will then count as the parent collider. Can also manually test-for and find your own parent, or test you are merely a child subcollider (a single collision will fire you and your parent's OnCollsion.)
Rigidbodies are meant to be frozen by setting isKinematic true. I wouldn't be surprised if there are some cases where a fully contrained RB acts differently from a kinematic one. The constraint system, again IMHO, is known to have combinations which just act odd.
Hi Owen, thanks for the reply.
Unfortunately, I can't freeze the rigid body using Is$$anonymous$$inematic, as I'm trying to detect collisions with static mesh geometry, and it looks like kinematic bodies won't interact with that!
It appears that the velocity on the rigid body in my case is always a zero vector, so I guess that is why the collision's relative velocity is also zero.
Incidentally, I tried using compound colliders as you described, but that seems to unearth another problem - I need to exactly track OnCollisionEnter and OnCollisionLeave events, but sometimes with multiple colliders parented by a single rigid body, the collision starts on one collider (and you get the Enter event), and then the collision transitions onto a second collider and when it leaves, you get no Leave event :(
I wonder if something like this would work for you. I have not tested this myself, just an idea:
static Vector3 getTrueVelocity(Rigidbody child_rigid_body)
{
Rigidbody parent_rigid_body=child_rigid_body;
while(true)
{
parent_rigid_body=child_rigid_body.GetComponentInParent<Rigidbody>();
if(parent_rigid_body==null)
return Vector3.zero; //failed
if(parent_rigid_body.velocity.sqr$$anonymous$$agnitude!=0)
return parent_rigid_body.velocity;
child_rigid_body=parent_rigid_body;
}
}
Glurth: try to check dates if you can (this is 4 months old.)
Of course, if you've had the problem, and Solved it, then feel free to add the solution the mostly relevant thread, no matter how old.
Your answer
Follow this Question
Related Questions
SImply yet tricky question about RELATIVE VELOCITIES... 1 Answer
Unity3D: Get Velocity after collision 0 Answers
Move Player Car in Forward Direction using Physics Force 1 Answer
(Steam VR / Vive) Rigidbody moving in only one direction after collision 1 Answer
Resume movement of instanced object relative to the original after instantiation. 2 Answers