- Home /
How to smooth (slow down) aircraft acceleration (Rigidbody2D)?
Greetings! I spent last week or so trying to resolve an issue, and did not succeed. In my game, I use physics (Rigidbody2D) and addForce to accelerate the aircraft. The force added is proportional to thrust.
The problem is as follows: if I add a lot of force, I reach realistically high speeds unrealistically quickly. If I add less force, I have realistic acceleration, but snails' top speed. I tried to play with drag, but the equation evens itself out: twice less force with twice less drag produce same acceleration and top speed. Increasing mass slows acceleration, but proportionally reduces max speed.
What I am doing now is having several drag equations depending on player's speed to limit the acceleration down to manageable levels, but it feels very clunky (not to mention unintuitive and unrealistic).
Here are snippets of my code:
//////////////////Adding thrust/////////////////////////////
rb.AddForce(transform.right*thrust); //thrust goes from 0 to 100
//////////////////Drag equations/////////////////////////////
if (rb.velocity.magnitude <= 3)
rb.drag = Mathf.Clamp(-rb.velocity.magnitude / 8f + 4f, 2.1f, 4f);
else if (rb.velocity.magnitude <= 4)
rb.drag = Mathf.Clamp(-rb.velocity.magnitude / 4.9f + 4f, 2.1f, 4f);
else if (rb.velocity.magnitude <= 7)
rb.drag = Mathf.Clamp(-rb.velocity.magnitude / 2.9f + 4.15f, 1.1f, 4f);
else if (rb.velocity.magnitude <= 10)
rb.drag = Mathf.Clamp(-rb.velocity.magnitude / 5f + 3.2f, 1f, 4f);
else
rb.drag = Mathf.Clamp(-rb.velocity.magnitude / 18f + 1.7f, 0.8f, 4f);
Speed conversion from units to km/h is as follows:
speedText.text = "Speed: " + Mathf.Round(rb.velocity.magnitude * 50 * 3.6f) + "km/h";
So rb.velocity.magnitude of 7 is 1260 km/h.
Without my drag equations the craft either boosts to 2500km/h almost instantly, or slowly accelerates to 500km/h and stays there. Am I missing something? How can I have high top speed AND slow acceleration?
Thanks in advance.
Update: If it is impossible, I would also like to know that. Although I doubt it - KSP has (moderately) realistic acceleration based on mass, drag and force, and KSP is made in Unity.
Answer by Flanker37T · Jun 28, 2016 at 04:52 AM
So I decided to stick with drag equations and found a "sigmoid" function, which is absolutely perfect for this case. After an hour or so of tinkering, I found the shape which works great for me (maybe it'll help somebody with a similar problem): 6/(1+e^(0.18(x-0.5)))+0.35.
, where x is rigidbody.velocity.magnitude.
Answer by ryanmillerca · Jun 14, 2016 at 09:37 PM
You might find the velocity change approach in the Unify Wiki's "Rigidbody FPS Walker" helpful, as it tackles a similar issue.
Thank you! I've played with that solution for a bit, but in the end stumbled upon the same wall. Here is what I added:
changeInVel = $$anonymous$$athf.Clamp(maxSpeed - rb.velocity.magnitude, 0, maxAccel);
rb.AddForce(transform.right*changeInVel*thrust);
But the problem is that if I set maxAccel to 1 (to get smooth acceleration), the object accelerates to a speed of ~13 (2350km/h), and then gets stuck due to drag (so setting max speed to anything higher than 13 is pointless), which is the exact same problem I started with. If I reduce drag, speed increases, but so does the acceleration. To counter this, I set lower acceleration, which again lowers speed. It's a cursed circle.