How to get the impact force of a collision in Unity

There are many scenarios where the force generated by a collision is necessary to perform certain actions, for instance dealing damage when a player falls to the ground. In fact we may calculate the damage to deal using the contact force of the collision with the ground, because the higher the height from which it falls, the higher the force will be (if nothing interferes with the fall). Let’s see how to get the collision impact force in Unity when a 3D or 2D collision occurs.

How to get the collision impact force in Unity 3D

Calculating the contact force of a 3D collision is very simple, in fact there is a property exposed that can be used to calculate it: all we need to do is call the impulse property from the collision instance and divide it by fixed delta time.

Usage example

Below an example on how to get the force generated by a 3D collision in Unity.

public class Character : MonoBehaviour { private void OnCollisionEnter (Collision collision) { float collisionForce = collision.impulse.magnitude / Time.fixedDeltaTime; if (collisionForce < 100.0F) { // This collision has not damaged anyone... } else if (collisionForce < 200.0F) { // Auch! This will take some damage. } else { // This collision killed me! } } }

If you are curious why we are dividing the impulse by delta time, below you have an explanation through Physics formulas. We basically have the impulse so through the second principle of dynamics we can obtain the force.

F = m • a or F = m • ∆v / t

impulse = F • t = m • ∆v

F (collision force) = m • ∆v / t = impulse / t

The total impulse is obtained by summing up the impulses applied at the collision contact points, Unity is directly providing it to us when dealing with 3D collisions.

How to get the collision impact force in Unity 2D

Obtaining the contact force of a 2D collision is not as easy as retrieving it from a 3D collision since there isn’t a impulse property exposed in the Collision2D class: we can’t just call it from the collision instance. Don’t worry, I created a workaround for that, I extended the class and added a GetImpactForce method just for you (well, it’s not true, I needed this in a personal project). Below the method that can be used to get the force generated by a 2D collision in Unity.

public static class Collision2DExtensions { public static float GetImpactForce (this Collision2D collision) { float impulse = 0F; foreach (ContactPoint2D point in collision.contacts) { impulse += point.normalImpulse; } return impulse / Time.fixedDeltaTime; } }

To use this method create a file named «Collision2DExtensions.cs» in your project, write the previous code inside it and take a look at the following usage example. The code in this method is following the same procedure defined for calculating the total impulse of a 3D collision: summing the impulses of the contact points. The total impulse is divided by fixed delta time to obtain the force.

Usage example

At the moment C# doesnt’t have extension properties but only extension methods, that’s why we have to call a method named GetImpactForce and not simply a property. But these are small details. Below a usage example.

public class Character : MonoBehaviour { private void OnCollisionEnter2D (Collision2D collision) { float collisionForce = collision.GetImpactForce(); if (collisionForce < 100.0F) { // This collision has not damaged anyone... } else if (collisionForce < 200.0F) { // Auch! This will take some damage. } else { // This collision killed me! } } }

I needed this particularly for a 2D project where the player takes damage and enters in a fall recovery state when falling from elevated heights. Another scenario for this would be the collision between two cars, you can damage the cars using a formula based on the collision contact force.

Conclusion

We have seen how to get the collision impact force in Unity 2D and 3D. This post is more focused on how to do it with 2D collisions since doing it with a 3D collision is pretty immediate and easy (and now it’s the same with 2D ones thanks to the method I provided to you). Hope it helps!

References

Below the references consulted during the writing of this post.