How do I stop my rotation on the dime?

Im trying to create the effect used in the descent game series that will allow me to rotate the player back to a right side up look at the world via attempting to rotate around the players z axis.

So far Ive got the player rotating, but cannot stop the rotation at 0 degrees and can only get the rotation in one direction.

Heres what Ive got so far, Ive been attaching this script to the Main Camera for testing.

using UnityEngine;

using System.Collections;

public class Player : MonoBehaviour { private float PlayerSpeed = 5; private float PlayerRotateSpeed = 50; public float PlayerBearingSpeed; private float PlayerZRotationToZero;

enum State
{
    Moving,
    Idle,
    Bearing
}

private State state = State.Idle;

void Update () 
{
    float amtToStrafe = Input.GetAxis("Horizontal") * PlayerSpeed * Time.deltaTime;
    float amtToMove = Input.GetAxis("Vertical") * PlayerSpeed * Time.deltaTime;
    float amtToRotateX = Input.GetAxis("Mouse X") * PlayerRotateSpeed * Time.deltaTime;
    float amtToRotateY = Input.GetAxis("Mouse Y") * PlayerRotateSpeed * Time.deltaTime;
    float amtToBearings = PlayerBearingSpeed * Time.deltaTime;

    transform.Translate(Vector3.forward * amtToMove);
    transform.Translate(Vector3.right * amtToStrafe);
    transform.Rotate(Vector3.down * amtToRotateX);
    transform.Rotate(Vector3.right * amtToRotateY);

    if ((amtToMove + amtToStrafe) == 0 && state != State.Bearing)
        state = State.Idle;
    else
        state = State.Moving;

    if (state == State.Idle && transform.rotation.z != 0)
    {
        PlayerZRotationToZero = transform.rotation.z;
        state = State.Bearing;
    }

    //Flip the ship right side up
    if (state == State.Bearing)
    {
        if (PlayerZRotationToZero >= 180)
            PlayerZRotationToZero -= amtToBearings;
        else
        {
            PlayerZRotationToZero += amtToBearings;
            amtToBearings *= -1;
        }

        transform.Rotate(0, 0, amtToBearings);

        if (PlayerZRotationToZero > 360)
        {
            //amtToBearings -= (PlayerZRotationToZero - 360);
            transform.rotation = new Quaternion(transform.rotation.x, transform.rotation.y, 0, transform.rotation.w);
            state = State.Idle;
        }

        if (PlayerZRotationToZero < 0)
        {
            //amtToBearings += Mathf.Abs(PlayerZRotationToZero);
            transform.rotation = new Quaternion(transform.rotation.x, transform.rotation.y, 0, transform.rotation.w);
            state = State.Idle;
        }

    }
}

}

Edit: Started messing with the script some more, still have not gotten anywhere however

1: I see in a few places you are doing some floating point math, and then comparing the result to 0. In general you cannot rely on floating point values to equal exactly 0.

For example, your tests for whether the player is moving or not look okay to me, as long as PlayerSpeed is explicitly set or clamped to 0.0 to stop the player moving. But if the speed itself is a calculated value it may never be exactly zero.

Same comment goes for amtToBearings, which is calculated from PlayerBearingSpeed.

The one I'm most suspicious of is on the line:

if (state == State.Idle && transform.rotation.z != 0)

Slight imprecisions would lead to rotation.z not being exactly zero. A more robust test is to test if the value is "close enough" to zero. You can do that using Mathf.Approximately.

2: The last two If statements can be combined into one. But a much better solution would be to use the same test that you used at the top when you decided to move from state Idle to Bearing. If the ending rotation is now close enough to upright, switch back to Idle.

If you do that, you can get rid of PlayerZRotationToZero entirely! Half your code is there just to maintain that variable.