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.

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. :frowning:

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.dragappliedspeed)/(1-0.01frigidbody.drag);

So, you can use Vector3 instead appliedspeed, and use it inside AddForce;
Good luck!

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;