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!

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.