- Home /
Calculating rigidbody top speed?
If I am applying a force to a rigidbody each FixedUpdate, is it possible to calculate or predict the maximum speed it will be able to reach?
It feels like there ought to be some calculation I can do using the force.magnitude, rigidbody.drag, rigidbody.mass, and probably Time.fixedDeltaTime. But I'm not sure what it is.
Answer by Jonatan Crafoord · Oct 05, 2012 at 12:36 PM
EDIT: After writing a long post about my own failed attempts at this I found the following forum post which accurately describes how to calculate Terminal Velocity: http://forum.unity3d.com/threads/34667-Terminal-Velocity
From that I derived the following calculation:
float topVelocity = ((addedForce.magnitude / rigidbody.drag) - Time.fixedDeltaTime * addedForce.magnitude) / rigidbody.mass;
Below is my old post, kept for reference but not very useful I suspect.
I would very much like to know this as well! This is how far I've got, maybe we can solve the problem together?
I also figured that the top velocity must be a function of the drag, the force you add and the mass. By setting mass = 1 or using ForceMode.Acceleration we can just ignore the mass for now.
I found a note on how PhysX calculates the drag force. Apparently it uses the following calculation:
dragForceMagnitude = velocity.magnitude ^ 2 drag*
The top speed should be when the dragForceMagnitude is equal to the magnitude of whatever force we are adding. When this happens, the drag vector balances out the added force. The rigidbody does not speed up or slow down, i.e. max velocity is achieved.
The forces must also use the same time measurement of course, which makes it a bit tricky as rigidbody velocity is in units per second and we're likely adding forces each FixedUpdate.
Anyway, the calculation should look roughly like this:
topSpeed = velocity.magnitude when dragForceMagnitude = addedForce.magnitude
So, trying to solve this, I inserted the PhysX calculation in the equation, getting this:
velocity.magnitude ^ 2 drag = addedForce.magnitude*
or, since topSpeed and velocity.magnitude is the same when this happens:
topSpeed ^ 2 drag = addedForce.magnitude*
Solving the equation for topSpeed, we get:
topSpeed = Sqrt(addedForce.magnitude / drag)
In Unity, using C#, the code would then look like this:
// The force you add each FixedUpdate using ForceMode.Acceleration or ForceMode.Force with mass 1
Vector3 addedForce;
// The top speed in units per second
float topSpeed;
// The equation
topSpeed = Mathf.Sqrt((addedForce.magnitude) / rigidbody.drag) / Time.fixedDeltaTime;
However, when I print this calculation the values I get are obviously incorrect. Doing a measurement, I found that for a drag value of 0.2, the object claimed a top speed that was 3.31 times as high as the speed it had when it was no longer accelerating. For a drag value of 0.5, the claimed top speed was 2.08 times the achieved top speed, so not even the same difference.
I suspect my error is somewhere in how I convert the added force per frame to units per second. It may also be some other mathematical error. Or, the PhysX calculation may simply be incorrect or outdated. :(
Answer by Nialit · Mar 12, 2013 at 09:06 PM
Hi! The formula of top phys speed, calculated from drag and force applied(in case of Force.Acceleration) is the next(my own research): topspeed = (rigidbody.drag*appliedspeed)/(1-0.01f*rigidbody.drag);
So, you can use Vector3 instead appliedspeed, and use it inside AddForce; Good luck!
Answer by Cameron_SM · Dec 02, 2014 at 09:14 AM
Unity seems to have a bug, rigidbody applies a basic stokes drag but does so after applying forces to the velocity so the velocity at the time of caculating the drag is actually incorrect (I've tested this, a lot, see my reply to the thread here for full explination: http://forum.unity3d.com/threads/terminal-velocity.34667/).
The workaround is to calculate the drag yourself and apply it directly, don't use the drag property of a rigidbody component as it's not applied correctly:
// a = acceleration, forward = transform.forward, dt = fixedDeltaTime
var drag = a / maxSpeed;
rigidbody.velocity += ((forward * a) - (rigidbody.velocity * drag)) * dt;
Your answer
Follow this Question
Related Questions
Add velocity relative to ground? 1 Answer
Predicting land position with drag applied 0 Answers
Rigidbody gain speed falling on slope 0 Answers
Turn-based vehicle physics 1 Answer
Predicting A Trajectory 1 Answer