How to rotate object to 180 opposite vector of motion?

I’m writing a playercontroller for a 2d space game a la Escape Velocity. I’ve got the basic controls–rotate left/right, move forward–working, but the “back” key, which should rotate the player so that they are facing exactly 180 degrees away from the vector of motion, is not coming together. I’m trying to do it by creating a variable “angleOfVelocity” paralleling transform.rotation.y and using that to figure out when and which direction to rotate, but it is just borked. Instead of stopping 180 away from vector, it stops rotating between ~50 and 303 degrees on transform.rotation.y. I have no idea why.

I’ve given up momentarily on rotating in the shortest direction, and am just trying to get it to stop at the right place. Any help is appreciated! (Also, if you can’t tell yet, I am a complete beginner to game programming.) Here is the code:

void FixedUpdate ()
	{
		float rotationChange = Input.GetAxis ("Horizontal"); 
		float moveForward = Input.GetAxis ("Vertical"); 
		Vector3 force;

		float angleOfVelocity = 0.0f;
		
		//want ship to rotate around, stopping once the key is released
		rigidbody.angularVelocity = new Vector3 (0.0f, rotationChange * rotationRate, 0.0f);

		//want ship to gain momentum in direction currently facing up, to topSpeed
		if (moveForward >= 0) 
		{
			force = transform.forward * acceleration * moveForward;
			rigidbody.AddForce (force);
			rigidbody.velocity = Vector3.ClampMagnitude (rigidbody.velocity, topSpeed);
			if (rigidbody.velocity.x > 0) //check if angle is going clockwise (like transform) or counterclockwise
			{
				angleOfVelocity = Vector3.Angle (Vector3.forward, rigidbody.velocity);
			}
			else //converting the shortest angle to 360
			{
				angleOfVelocity = 360 - Vector3.Angle (Vector3.forward, rigidbody.velocity);
			}
			Debug.Log ("angle of velocity: " + angleOfVelocity);
		}
		else
		{
			//want to make it rotate towards opposite of angle of motion
			if (Mathf.Round(angleOfVelocity) != Mathf.Round(transform.rotation.y))
			{
				rigidbody.angularVelocity = new Vector3 (0.0f, -moveForward * rotationRate, 0.0f);
			}
		}

		//arcTan = Mathf.Rad2Deg *(Mathf.Atan (rigidbody.velocity.x / rigidbody.velocity.z));
		//Debug.Log ("velocity: " + rigidbody.velocity + "   angle: " + transform.eulerAngles + "   arctan:" + arcTan);
		//Debug.Log ("force: " + force + "   velocity: " + rigidbody.velocity);

}

Replace the “else” block of your function with this, and “downward” movement input should make your vehicle turn to face away from the direction of movement. Note that it does nothing when there is no movement.

Also worth mentioning that directly assigning to the rigidbody.angularVelocity will produce strange results when this vehicle interacts with other physics-driven objects. Even though it’s a tremendous pain in the butt and requires some physics-related math, the proper way to drive a rigidbody vehicle’s rotation is with rigidbody.AddTorque();

However, when you’re just getting started, it’s probably better to approach these things as simply as possible, so just worry about that when you get there. Good luck! :slight_smile:

//want to make it rotate towards opposite of angle of motion			
// check velocity magnitude, since this operation makes no sense unless there is movement
if ( rigidbody.velocity.sqrMagnitude > 0.01f ) {				
	float sign = Mathf.Sign( Vector3.Cross( transform.forward, -rigidbody.velocity ).y );				
	rigidbody.angularVelocity = new Vector3( 0, sign * rotationRate, 0 );				
}