Velocity data from OnCollisionEnter is delayed (incorrect)

I'm trying to do damage calculations between game objects on a collision. The damage will be based on the velocity of each game object during the collision. The problem is that the velocity data seems to be delayed. In other words, the velocity for each object that I read during OnCollisionEnter is the updated velocity shortly after the collision. As a test, I did the following:


Object A is stationary → velocityA = (0, 0, 0)

Object B moves directly towards Object A → velocityB = (0, 0, 32)


void OnCollisionEnter(Collision collision){
   // Get initial data
   Vector3 theirVelocity = collision.rigidbody.velocity;
   Vector3 myVelocity = collision.relativeVelocity - theirVelocity;

   Debug.Log ("My velocity: " + myVelocity + "	Their velocity: " + theirVelocity);

I would expect that the 'Their Velocity' value would be (0, 0, 0) because they were stationary right before the collision, but instead their velocity is (0, 0, -10.6) which is what their velocity is directly after the collision. I also tried this using collision.rigidBody.velocity, but that returns the same value.

One thing I noticed is that if Object A is against a wall or in a corner when I hit it, the 'Their velocity' value does return (0, 0, 0). I assume this is because Object A has nowhere to go and therefore Object A's velocity doesn't actually change from (0, 0, 0).

Is there a way to get the velocity data of each game object directly before the collision takes place?

Yes, there is a way. You need to save the velocity during fixed update. If you take a look at
Unity’s Execution Order in the Physics section, you can see that there is an Internal physics update, this is where I think every rigidbody is moved, and every velocity is updated as a result of collisions, then, after that physics update comes OnTrigger on Collision and Coroutines waiting for fixed update, that is why you are getting the affected velocity and not the one before the collision. Like I said if you want velocity before collision, you will need to have a field on your script where you will save the velocity every Fixed Update. Something like this:

private Vector3 velocityBeforePhysicsUpdate;

void FixedUpdate()
    velocityBeforePhysicsUpdate = rigidbody.velocity;

So when you check velocityBeforePhysicsUpdate inside your OnCollision or OnTrigger methods, the field should contain the velocity you’re expecting.

Hope this helps!

I know this is old, but i have a question.
The solution above works, but it is very performance unfriendly.
I don’t want to save the velocity every physics frame, I only want to save it, when the object is actually colliding.
Does anybody have an idea how to achieve this? I looked into every forum question about this topic, but nobody seems to have a better solution than just bruteforcing it.
This can’t be the only way :frowning:

@lennardbeers I found a solution for my particular case. I set my colliders to be triggers and used OnTriggerEnter2D instead of OnCollisionEnter2D. I suppose the trigger triggers before the collision does! :slight_smile:

The truth is , it is the most idiotic collusion handling I have ever seen. If you want to handle the collusion yourself , you will need the velocity before the collusion, not after. Another unity spastizm … they did not even feel the need to add another event for OnBeforeCollusion. They are unbelievable. I realized that after giving a great amount of fight with unity , you have to deal with it … Just change your collusion to trigger and handle everything yourself. Much better than keeping record of last velocity and wasting process time every frame .
*** The thing is , when you do OntriggerEnter, you have to calculate the contact point and the normal yourself, which is also a pain in the *rse .

One more time , Thank you unity, for making everything harder than it supposed to be.