I've tried to understand the Maths behind AddForce
, as to reproduce it using rigidbody.velocity +=
.
Based on the formulas provided by PhysX documentation for AddForce, we have:
eFORCE parameter has unit of mass * distance/ time^2, i.e. a force
eIMPULSE parameter has unit of mass * distance /time
eVELOCITY_CHANGE parameter has unit of distance / time, i.e. the effect is mass independent: a velocity change.
eACCELERATION parameter has unit of distance/ time^2, i.e. an acceleration. It gets treated just like a force except the mass is not divided out before integration.
I tried to convert these formulas above to a rigidbody.velocity +=
syntax, but I am unable to get the Maths right.
Here is what I got working:
float force = 3f;
public void FixedUpdate() {
// Same as r.AddForce(force, ForceMode.Force)
Vector2 distance = (force / r.mass) * Time.fixedDeltaTime;
r.velocity += distance;
}
float force = 3f;
public void FixedUpdate() {
// Same as r.AddForce(force, ForceMode.Impulse)
Vector2 distance = (force / r.mass);
r.velocity += distance;
}
I tested both of them, by superposing two rigidbodies, one using AddForce
, while the other used r.velocity+=
. So far, it seem my convertion is correct as they move exactly the same.
As for the Maths I am not getting right, here is what I came with:
eFORCE = mass * distance/ time^2
eFORCE / mass = distance/ time^2
(eFORCE / mass) * time^2 = distance
distance = (eFORCE / mass) * time^2
Same as ?
Vector2 distance = (force / r.mass) * Time.fixedDeltaTime;
That woud mean time^2
is equal to Time.fixedDeltaTime
.
Then let's do the same for ForceMode.Impulse
:
eIMPULSE = mass * distance /time
eIMPULSE / mass = distance / time
(eIMPULSE / mass) * time = distance
Meaning time
is Mathf.Sqrt(Time.fixedDeltaTime)
?
Well, as you guessed, on the terrain this doesn't check out.
I like to get the Maths right, how do I get to the result c# code I have shown (that seem correct) starting from the PhysX documentation ?
time^2
is equivalent totime*time
, so moving that to the delta version, wouldn't it beTime.fixedDeltaTime * Time.fixedDeltaTime
? \$\endgroup\$time^2
should beTime.fixedDeltaTime * Time.fixedDeltaTime
forForceMode.Force
, but the formula that is working when testing isdistance = (force / r.mass) * Time.fixedDeltaTime
, notdistance = (force / r.mass) * Time.fixedDeltaTime * Time.fixedDeltaTime
. I made the assumptiontime^2
is somehow equivalent toTime.fixedDeltaTime
. But this assumption is wrong when testing that onForceMode.Impulse
. \$\endgroup\$