- Home /
Physics: Auto-stopping a spaceship with reverse thrusters
I'm playing with a concept for a spaceship game with physics. I have three rigidbody objects attached with fixed joints: a hull, a main engine, and a reverse thruster. There is no drag or angular drag. There is no gravity. The main engine and reverse thruster both have a "Thrust" script attached which uses AddForce to propel the ship forward or backward.
My goal is to create an "auto-stop" function for the ship. Basically, whatever the ship's (hull's) velocity is, I want a script to manipulate the engines' thrusts so the ship reaches a standstill.
As a test, I've been using the Z-axis only. The following code runs from an Update()...
void Stop ()
{
Vector3 velocity = ship.GetComponent<Rigidbody>().velocity;
Vector3 heading = ship.gameObject.transform.forward;
float vx = velocity.x;
float vy = velocity.y;
float vz = velocity.z;
float hx = heading.x;
float hy = heading.y;
float hz = heading.z;
if (velocity != Vector3.zero)
{
if (vz == 0)
{
Debug.Log ("The ship is not moving on Z");
}
else if (hz > 0 && vz > 1)
{
mainEngine.GetComponent<Thrust>().output = 0;
reverseThruster.GetComponent<Thrust>().output = reverseThruster.GetComponent<Thrust>().maxThrust;
}
else if (hz > 0 && vz > 0)
{
mainEngine.GetComponent<Thrust>().output = 0;
reverseThruster.GetComponent<Thrust>().output = 1;
}
else if (hz > 0 && vz < -1)
{
reverseThruster.GetComponent<Thrust>().output = 0;
mainEngine.GetComponent<Thrust>().output = mainEngine.GetComponent<Thrust>().maxThrust;
}
else if (hz > 0 && vz < 0)
{
reverseThruster.GetComponent<Thrust>().output = 0;
mainEngine.GetComponent<Thrust>().output = 1;
}
}
else
{
Debug.Log ("The ship is stopped");
mainEngine.GetComponent<Thrust>().output = 0;
reverseThruster.GetComponent<Thrust>().output = 0;
}
}
It seems to work decently, though the ship never actually come to a complete stop. It still moves at a thousandth of a unit every second or two.
Should I move the code to work from a FixedUpdate() instead? Do I need to kill the engines and add in a small delay between checks, and if so, how? Or would I be better off just zeroing out the velocity directly through the script when it gets so low?
Thank you so much!
Invert the velocity and greatly reduce its magnitude. Add the result to the velocity periodically.
Thanks. Yes, I was using the different engines to counteract each other when necessary. And I did end up having to lower their outputs when the ship got slower. It ended up working quite well for one axis.
Answer by salex100m · Mar 01, 2015 at 05:28 AM
I don't think you can ever get to true ZERO velocity by adding and subtracting thrust. It would be much cleaner to just implement a fullStop() function that says:
if (currentVelocity < minimumV && currentVelocity > -minimumV ) then velocity = 0
basically... force a stop when you reach some minimum threshold.
Thank you. It may come to that for all three axes.
I actually got a full-stop on one axis by adding more $$anonymous$$ute velocity checks and lowering outputs to match.
I also moved it to FixedUpdate(), so that may have helped also.
Your answer
Follow this Question
Related Questions
Constraining maximum movement speed on a rigidbody on certain axes. 1 Answer
Detecting when my character is not moving? 1 Answer
Need help with my movement script.. :( 1 Answer
(RigidBody) Velocity at an Angle 0 Answers
How can I make 2D movement less jerky on a controller, with velocity and such? 0 Answers