- Home /
Accelerate a rigidbody towards max speed
Hey guys,
I'm currently in the process of creating a naval game, and I have been trying to find a way for the ships (which have rigidbodies) to accelerate or decelerate to a certain speed. Drag will affect the ships. Any ideas on how I would approach this problem?
Thanks!
(By the way, I am aiming for movement similar to that of World of Warships.)
Answer by Bunny83 · Jun 17, 2018 at 02:21 PM
Since it seems you use drag, have a look at my answer over here
You may want to use the "GetRequiredAcceleraton" method. Keep in mind that the required force is just the required acceleration multiplied by the object's mass. Though you can simply use ForceMode.Acceleration. When using ForceMode.Force Unity simply divides the incoming force by the mass to determine the acceleration internally.
Thanks for your reply, it works beautifully! One thing though, is there any way I can slow the acceleration (for a more realistic effect, since my game involves ships) but still reach the target velocity? Edit: Could this be applied to turning?
$$anonymous$$y method just calculates the $$anonymous$$imum required acceleration to sustain the targetspeed. If you want a more realistical behaviour you may want to lower your drag which will automatically lower the required acceleration. On top of that you can always ramp up your actually used acceleration over time until you hit the required acceleration.
Note that Unity's way to calculate drag is not correct. Drag in the real world usually increases quadratically in relation to the velocity. Unity just lowers the velocity by a certain percentage. Ins$$anonymous$$d of using the built-in drag you can set it to 0 and apply your own drag manually.
I'm not sure what you mean by "turning" and what you mean by "applying" in this context.
Well never$$anonymous$$d turning (and slowing the acceleration I just figured out). But thanks for your great response!
EDIT: By turning, I meant to ask if I could use your formulas to accelerate a ship until it turns a specific number of degrees per second.
Answer by ImpOfThePerverse · Jun 16, 2018 at 05:28 PM
It's called a PID loop, though you'll only be implementing the "D" (derivative) part of it. You compute a Vector3 that is the target velocity (how fast you want the ship to go). Subtract the ship's actual velocity from it, and multiply by a constant to get a force. The force will be high when the ship is far from the target velocity, and zero when the two match.
Vector3 targetVelocity = transform.rotation * Vector3.forward * targetSpeed;
Vector3 force = (targetVelocity - rb.velocity) * forceMult;
rb.AddForce(force);
Edit - Since you're modeling ships, you might want to clamp the force so that it doesn't exceed the maximum thrust of the ship.
if (force.magnitude > forceMax)
{
force = force.normalized * forceMax;
}
Thanks for the reply! So just to make sure,
targetVelocity
can be a constant,force$$anonymous$$ult
controls how quickly my ship speed up,And I can clamp the maximum amount of force used?
targetSpeed is a constant, a public variable set in the inspector or calculated from stats and user input (like all ahead full, impulse, etc.). targetVelocity gets computed each frame, since even if the targetSpeed hasn't changed, the ship's rotation might have. To clamp the acceleration to the ship's maximum thrust, insert the second bit of code I edited in there in between lines 2 and 3. So you calculate target velocity, then calculate the force, then clamp the force with the inserted code, then apply the force. force$$anonymous$$ult deter$$anonymous$$es how quickly ships speed up, with force$$anonymous$$ax limiting it based on the ship's maximum thrust.
I just want to add that this is not the "D" part of a PID controller but just the "P" part. However if you want to use a PID controller to cope with drag you need at least a PI controller. The D part is not really required as it mainly handles sudden changes in the error. So the faster the error goes up / down the more correction is applied in order to damp the error increase. The P (propotional) part is the usual direct correction that you actually do in your code. Wikipedia actually has a decent description of the 3 parts.
The tricky part when using a PID controller is to fine tune the 3 parts to represent your desired behaviour.
Thanks for your reply, but I can't understand it with -100 IQ! :D
hello can you help with my issue please (Link to my issue)