# getting impact FORCE, not just velocity?

Discussion in 'Editor & General Support' started by Tom163, May 26, 2009.

1. ### Tom163

Joined:
Nov 30, 2007
Posts:
1,049
Is it possible to get the impact force of a collision, instead of just the relative velocity, or do I have to dig up my physics books and do all the calculations myself?

I figure there must be a way, since Unity already uses force to determine if joints break, but the Collision class only gives me velocity, not force.

tribio likes this.
2. ### Lucas Meijer_old

Joined:
Apr 5, 2008
Posts:
436
Hey,

It's hard to help going on this question. Are you talking about explosions as in RigidBody.AddExplosionForce() ? Or something else?

What is it you're actually trying to do?

Bye, Lucas

3. ### Tom163

Joined:
Nov 30, 2007
Posts:
1,049
No, I'm talking about collisions between rigidbodies or rigidbodies and colliders. Aka "player moves into wall", "crate falls on player" or "moving crate crashes into crate standing still".

The physics already does force calculations, otherwise it could not properly simulate a light crate bouncing into a heavy crate.

It just seems that information is never disclosed? Definitely not in the collision data.

### Unity Technologies

Joined:
Aug 18, 2005
Posts:
1,635
As far as my understanding of physics goes, there is no such concept as a collision force, just a collision impulse. That is because force is always applied over an interval of time, whereas a theoretical collision would just be a point of time. The rules you'll find in your physics book (or wikipedia, if you don't have books handy), will probably not deal with forces either, but just give you the resulting velocities for two bodies after a collision.

If you just want a measurement of how strong the hit was (like, for example for damage calculations), the dot product of collision normal and collision velocity (ie the velocity of the two bodies relative to each other), times the mass of the other collider should give you useful values.

chipb and enderdragonzend like this.

Joined:
May 20, 2009
Posts:
402
6. ### zelk

Joined:
Mar 13, 2009
Posts:
246
Actually, there are other forces involved that exist but cannot be reached, from what I understand. That is, normal forces between the object and the ground.

In my project, I need to find out the normal force between the tire and the ground, to be able to create a correct tire friction model. However, I have no idea right now how to get it. The physical engine must know this (I guess) to be able to do the math... but it cannot be reached. If the vehicle is standing still or moving on a flat ground, there are no vertical velocity change, BUT, there is definetly a force present that makes sure the vehicle do not fall into the ground.

Does anybody have other ideas how to get this information or calculate it? I'm a bit stuck for the moment...

Right now, I am thinking about simulating it by checking how the vehicle body is moving, if the tire is touching the ground and the status of each ConfigurableJoint. But, I would like to get better results that this simulation.

/Ricky

7. ### andeeeee

Joined:
Jul 19, 2005
Posts:
8,768
Unless the physics has to be very accurate (so you can break objects that you run over, say) then good results can usually be achieved with raycasts. If you send a raycast down from a suitable suspension anchor point, you can use it to measure the distance to ground. Assuming the wheel itself is incompressible, you can use this distance to calculate the compression of the spring, and hence the force pushing down on the road. This technique certainly has its limitations, but it generally gives quite an impressive result (this is basically how Unity's wheel colliders work, for example).

8. ### zelk

Joined:
Mar 13, 2009
Posts:
246
Yes, the raycast method is reasonable but as you say, not perfect. I would like to be able to drive on unstable bridges etc. but still, it could work good enough for now... but I have created my own model instead of the PhysX Wheel Collider because it is not good enough for more than very simple vehicle games... so the raycast is my last chance.

I have physical wheels with ConfigurableJoints as suspension... and a physical material totally without friction... so if I turn off my friction model calculations, the vehicle slips around as if on ice in all directions in the landscape. Then, my friction model handles lateral friction and acceleration, breaks etc. Also about to finish up a very flexible drive line (e.g. multiple engines, multiple diffrentials etc.)... that's why a raycast to get the normal forces is a bit booring... when everything else is so physically correct.

If anybody knows of an even more accurace idea for getting normal forces, please write.

/Ricky

9. ### rom

Joined:
Jul 2, 2006
Posts:
265
Code (csharp):
1.
2.     public static float KineticEnergy(Rigidbody rb){
3.         // mass in kg, velocity in meters per second, result is joules
4.         return 0.5f*rb.mass*Mathf.Pow(rb.velocity.magnitude,2);
5.     }
6.

10. ### SilentWarrior

Joined:
Aug 3, 2010
Posts:
107
Hello, I have almost the same problem as the original poster.

In my case, I want to get the force generated by a collision so that I can explode the a projectile that hits a surface or another rigidbody, why?

In my game, projectiles can bounce off the armor of other tanks. So, in order to get a realistic behavior, I would want the projectiles to explode past a fixed threshold of force generated, this is because different tanks have different types of armor, for example, lateral armor can be as simple as a straight block of metal paralel to the Y axis like so :

<-- means direction of projectile
O==== means projectile in motion
and the other ascii is supposed to picture the armor design

Heavy and Light tanks :
Plain (will make it bounce off without dissipating force first, full headon impact)
| <-- O====
It can also be deflective (make it bounce up, thus dissipating some force and projectile will bounce away from tank) :
\ <-- O====
Bit more complex deflective (same effect as before)
) <-- O====
Explosive (will explode on impact with a force applied in the opposite direction thus dissipating and destroying the projectile)
|::: -<-- O====

Light armor vehicles like jeeps have a very weak armor, thus, shells can hit them and not blow up, destroying them by simply the force of the impact.

The force of the impact would be used to calculate if the shell is to bounce or explode on impact and what type of explosion (effect) it would cause.

PS: I hope i am not mistaken, but, I think the G-force is what I mean by the force generated by an impact. (at least is what they use on TV programs and movies as a unit of messurement)

PS2: effect is meant to emulate something like this : http://www.youtube.com/watch?v=t459NbF5Vek

Joao Carlos

11. ### zelk

Joined:
Mar 13, 2009
Posts:
246
You should be able to use the velocity of your two colliding objects before and after the collision to calculate this.

12. ### SilentWarrior

Joined:
Aug 3, 2010
Posts:
107
Is there any onBeforeColision? There is a OnCollisionEnter, but that happens once the collision has taken place.

Also, I am using the impact force like this:
Code (csharp):
1.     float impactforce = collision.impactForceSum.x+collision.impactForceSum.y+collision.impactForceSum.z;
2.         if (explodeOnImpact || impactforce>70 || impactforce<-70/* || collision.transform.name != "Terrain"*/){
3.             explode (contact.point, rotation);
4.         }
But I get very mixed results, such as negative numbers and collisions that visually seem very strong but arent detected as such, and others that are very shallow in angle and are detected as big collisions. I would like a generic impact G-force type value that I could work with (with g-force like approximation i could read information about the actual weapons and get some proper info into the game, ajusting after that until it seems realistic), any ideas?

13. ### Rapzid

Joined:
Apr 25, 2009
Posts:
123
I would just like to bring attention to this again. This is working as expected for me:

Code (csharp):
1. Vector3.Dot(col.contacts[0].normal,col.relativeVelocity) * rigidbody.mass
I would also like to say that I'm not very impressed this information is unavailable through the physx API. I'm not very impressed with physX at all TBH.

Last edited: Dec 30, 2011
Kamil1064, Jubcow, Tehelee and 2 others like this.
14. ### markhula

Joined:
Sep 3, 2011
Posts:
630
Hi all,

Yep I have the same issue.
Rapzid ; your suggestion doesn't work for me; not sure why (sometimes I just get zero)
I have a hammer you can raise and then 'release' to hit an object; I need to know the 'force' to determine how much damage is applied to the hit object. I could 'cheat' as the hammer is kinematic so as you raise it higher I could (in theory?) increase it's mass.
Not sure how reliable this would be - don't need realistic but some way of measuring the impact

cheers

15. ### Nutella

Joined:
Feb 1, 2013
Posts:
1
Hi guys,

this thread has been placed long ago in 2010 and the thread creator may have already solved in.

but i'll put my working implementation just in case somebody looks this up.

void OnCollisionEnter(Collision collision){
//on collision with something, start a coroutine
StartCoroutine("OnImpulse");
}

IEnumerator OnImpulse(){
Vector3 initialVelocity,newVelocity;
//get velocity
initialVelocity = transform.rigidbody.velocity;

//wait for new updates, by trial and error, 3 frames seems to get me the correct effect.
yield return null;
yield return null;
yield return null;

//get new velocity
newVelocity = transform.rigidbody.velocity;

//impulse = magnitude of change
Vector3 result = initialVelocity - newVelocity;

Debug.Log ("Impulse taken: " + result.magnitude);
if(result.magnitude > minForceToBreak){
Destroy(gameObject);
}

}

Let me explain. Impulse force on an object is determined by the instantaneous change in velocity.

which in this case i have estimated by measuring change in velocity over 3 frames as what i have done. the reason for 3 frames is by trial and error as it seems to net me the best stable result in my case. As sometimes when determined over 1 frame, it kinda misses the computation.

Good luck and all the best guys!

Mikael-H, Okido and grandtheftaural like this.
16. ### grandtheftaural

Joined:
Dec 11, 2014
Posts:
1
Hey @Nutella, thanks for posting this script last year! It works well, I've been playing with it quite a bit. If I end up doing any interesting modifications to it, I will post here. Thanks again! Cheers.

17. ### Delforce

Joined:
Jun 3, 2015
Posts:
15
grandtheftaural, you mentioned that you've done interesting modifications to the script. Any chance you can post it as you mention you would?

18. ### CakeMedia

Joined:
Sep 26, 2013
Posts:
2
Since no one has answered yet, I'll leave a scrip that gives you the impact force of two colliders:
Code (CSharp):
1. Vector3.Magnitude(GetComponent<Rigidbody>.velocity);
It goes into "OnCollisionEnter", obviously.

19. ### Nition

Joined:
Jul 4, 2012
Posts:
757
Er, that just gets the current velocity vector magnitude of the object that's being hit.

20. ### Astiolo

Joined:
Dec 18, 2014
Posts:
27
TheGameLearner likes this.
21. ### Nition

Joined:
Jul 4, 2012
Posts:
757
The previous posts in this thread were made before Collision.impulse existed (it was first exposed in Unity 5.2). Good to know about for people coming to this old thread now though.

TheGameLearner likes this.
22. ### SpaceManDan

Joined:
Aug 3, 2013
Posts:
15
@Astiolo

You nailed it man. collision.impulse.

23. ### TooManySugar

Joined:
Aug 2, 2015
Posts:
864
This worked perfectly. Its 2016 but using 4.6.9.

void OnCollisionEnter (Collision collider)
{

if ( KineticEnergy (collider.rigidbody) >= breakEnergy){//energia minima para que se rompa

Debug.Log ("oobject broken");
}

If collision energy is greater than break energy then I add kolliders so I can trash street furniture as I runover them with a tank. Thanks!

24. ### samifruit514

Joined:
Mar 27, 2015
Posts:
28
Collision2D.impulse is not available yet (not even in 5.4 beta)

@Nutella: Your method is interesting but shouldn't we use WaitForFixedUpdate instead of yielding update frames? Im not sure how this could be done...

25. ### TMPxyz

Joined:
Jul 20, 2012
Posts:
765
I'm kinda confused by the Collision.impulse here.

I've made two cubes (A & B) to go against each other, and output the collision.impulse in each one's OnCollisionEnter().

I suppose A & B would output impulse vector in opposite direction, but they're the same.

26. ### OculusFan

Joined:
Nov 6, 2014
Posts:
3
I'd like to learn more about Impulse as well. Why are the input vectors the same on both OnCollisionEnters? And I know this is a very beginner question but how do I compare the two Vector3 Impulse results to determine which is greater?

update:trying to see if the magnitude of the vector is what I need to compare the two.
update: I guess it is pretty obvious why the impulse would be the same given the first law of Newtonian physics.

So that makes it hard to say exactly what I want. I want to determine what object hits the other in the way that most impacts its velocity. The idea here is that the "Cube" that hits the other cube the hardest remains in control (by allowing that cube to apply drag) but the other cube slides out of control. I guess that has to do with an earlier reply that suggested using the velocity and the normals but I still haven't figured out how to do that. I wish it was easier to find more info about this.

update: I guess I should use relativeVelocity? and then multiply by the mass to get an idea of who hits harder if they are both moving directly toward another? I'm not sure how relativeVelocity is defined but I'm basing it on this video.

update: Nope, it looks like relativeVelocity is the same for both objects as well. Hmm. I'll try something else.

update: It looks like I want to compare mass times velocity in the rigidbody. Which I guess is momentum? It won't take into account the angle of the collision but I guess for my purpose and skill level it will be good enough.

update: Well that kind of works but something is off. It looks like the collision occurs some time after the point of impact within the physics engine. I think someone else in this thread was addressing that issue. Hopefully, I can make use of that.

update: I tried to add an extra trigger around the cube slightly larger than the cube to get the velocity of the cubes before impact, but for some reason that doesn't work.

update: I tried getting the velocity in FixedUpdate and then I assign that value to another value in OnTriggerEnter. That seems to work. I notice that the value is double. I guess because a collision spreads the velocity into the next object? I'm definitely going to be studying physics on top of everything else I'm learning.

Last edited: Dec 10, 2016
27. ### VindictPL

Joined:
Apr 14, 2015
Posts:
1
I had similar problem and after trying all solutions I have found on the internet I discovered that while Collision2D still doesn't have "Impulse" property, as Collision does, ContactPoint2D has normalImpulse property, so to calculate impulse one could do something like this

Code (CSharp):
1. void OnCollisionEnter2D(Collision2D c) {
2. float impulse=0f;
3.         foreach (ContactPoint2D cp in c.contacts) {
4.                 impulse += cp.normalImpulse;
5.         }
6. }

28. ### Ultroman

Joined:
Mar 10, 2014
Posts:
61
This is awesome, but I just wanted to chime in and say that we can substitute the .magnitude call (which would save us a squareroot call, since I believe magnitude is only calculated when referenced, but I could be mistaken), by instead doing:
Code (CSharp):
1.     public static float KineticEnergy(Rigidbody rb){
2.         // mass in kg, velocity in meters per second, result is joules
3.         return 0.5f*rb.mass*rb.velocity.sqrMagnitude;
4.     }

SparrowsNest likes this.
unityunity