- Home /
Convert rigidbody.drag to acceleration(m/s²)?
Drag afaik is kinda modifying velocity every FixedUpdate like:
velocity *= 1-Mathf.Clamp01(drag*Time.fixedDeltaTime);
or maybe
velocity -= velocity*Mathf.Clamp01(drag*Time.fixedDeltaTime);
or something like that (found on forums). Is the conversion even possible? I'm pretty sure that 0 drag = 0 deceleration and 1/Time.fixedDeltaTime drag = infinite deceleration (which makes it dependent on fixedDeltaTime, tested, looks like a bug). So I ended with constructions like:
dragFactor = 1-Mathf.Clamp01(drag*Time.fixedDeltaTime);
deceleration = 1/dragFactor; //can't be <1, wrong proportions
or even
deceleration = 1/Mathf.Pow(dragFactor,1/dragFactor); //can't be <1 too, relatively right proportions
What I'm doing is replacing rigidbody bullets with raycasts based on their parameters. What I'm trying to find is stopping distance (S = v0^2 * 2*a) and speed after some distance traveled (v = v0^2 - 2aS). This strange formula that I found by scratching my head and randomly swapping numbers and operands for like two days is kind of worked:
float StopDist(float speed, float drag) {
float dragFactor = 1-Mathf.Clamp01(drag*Time.fixedDeltaTime);
return speed * Mathf.Pow(dragFactor,1/dragFactor);
}
but failed on high drag / low distances. And this is like for speed after traverse:
float CurrSpeed(float initSpeed, float drag, float dist) {
float dragFactor = 1-Mathf.Clamp01(drag*Time.fixedDeltaTime);
float deceleration = 1/Mathf.Pow(dragFactor,1/dragFactor)-1; //-1 is temporal workaround
return initSpeed-Mathf.Max(0,dist*deceleration);
}
I'm only need these two formulas (even based on drag), but conversion is much much better.
Drag is unfortunately one of those variables that has very bad description, so it is unclear what it does exactly. But what you wrote, that it is modifying velocity in FixedUpdate() based on fixedDeltaTime seems to be correct.
In which case, I would use the following conversion (NOTE: I have NOT tested this, just used the info you gave to shape it into a script):
public class DragToDeceleration : $$anonymous$$onoBehaviour {
private Rigidbody ownRigidbody;
private float dragToSimulate = 0;
private void Awake () {
ownRigidbody = GetComponent<Rigidbody>();
UpdateDragToSimulate();
}
private void UpdateDragToSimulate () {
if (ownRigidbody.drag != 0) {
dragToSimulate = ownRigidbody.drag;
ownRigidbody.drag = 0;
}
}
private void FixedUpdate () {
UpdateDragToSimulate();
ownRigidbody.velocity *= 1 - $$anonymous$$athf.Clamp01(dragToSimulate * Time.fixedDeltaTime);
}
}
This is how to simulate drag (description what drag does, not conversion) - that's what I'm already know. The thing I need is deceleration value (in meters per second squared) "extracted" from drag to use in formulas. Or maybe specific formulas for stopping distance and speed after traverse that are using drag directly (which I told in op-post, btw).
Ah, you are right, now I understand. The velocity change would be ownRigidbody.velocity * $$anonymous$$athf.Clamp01(dragToSimulate * Time.fixedDeltaTime), this is already in the same unit as the velocity (meters / second if you interpret a unit distance as 1m). And if my physics knowledge doesn't fail me (which is quite possible), the deceleration is actually dragToSimulate!
Your answer