Problem Rotating up vector of camera to mouse position on screen.

I am working on a control script for a psuedo-aircraft in motion using mouse controls. The center of the screen (Screen.width/2, Screen.height/2) has a crosshair and I have a custom cursor at the mouse position. What I am having difficulty with is rotating the z-axis of the camera/player so that the camera up direction points in the same direction that the mouse is from the center crosshairs. Or, to try to explain more clearly, when the player moves the mouse from the center of the screen over to the top-right corner of the screen, the camera and player objects rotate on the z-axis (only!) so that the top-right corner is now "up" to them. If you put the mouse pointer in the bottom center of the screen, the camera would rotate so that it was upside down (and the up vector of the camera would share the same z rotation as the angle from center of the screen to the cursor). I have the following code:

var mouseX: float = Input.mousePosition.x - Screen.width/2;
var mouseY: float =-((Screen.height-Input.mousePosition.y) - Screen.height/2);
var mouseAngle:float = Mathf.Atan2(mouseY,mouseX)*Mathf.Rad2Deg;
    if (mouseAngle <0) mouseAngle+=360;

var airAngle:float = Mathf.Atan2(Camera.main.transform.up.y,-Camera.main.transform.up.x)*Mathf.Rad2Deg;
    if (airAngle <0) airAngle+=360;

var tempRoll: float = Mathf.MoveTowardsAngle(airAngle,mouseAngle,360);
var deltaRoll: float = tempRoll - airAngle;
    if (Mathf.Abs(deltaRoll) < 5.0) deltaRoll = 0.0;
// Rotate transform ---------------------------------
transform.Rotate(0,0,-deltaRoll* Time.deltaTime);

This works... but only as long as my camera is facing forwards. As soon as I rotate around the Y axis or X axis, this code doesn't work (the target angle is not correct and the camera does not spin the correct way). I know I'm missing something simple (and the way I'm doing this is killing my framerate!), but I can't seem to get this to work correctly. Any advice would be appreciated!


I still have the same issue, but I've approached it from a better direction (I think). My new code is:

    var mouseVector: Vector3 = Vector3(Input.mousePosition.x - Screen.width/2,-((Screen.height-Input.mousePosition.y) - Screen.height/2));
    var mouseAngle: Vector3 = mainCam.transform.TransformDirection(mouseVector.normalized);
    var mechAngle: Vector3 = transform.InverseTransformDirection(transform.up);
    var moveAngle: float = Vector3.Angle(mechAngle,mouseAngle);
    if ((mechAngle.x-mouseAngle.x) >0) moveAngle *= -1;
    Debug.Log(mouseAngle.ToString()+" and "+transform.up.ToString());


It still works fine facing forward on the origin... but as soon as I move anywhere else or rotate the model around the y-axis, I get random rotations.

Tl;dr (sorry). But if you want a psuedo aircraft script, try this one out. (Copy from similar answer).

Simple aircraft script.

public class Aircraft : MonoBehaviour
    public float flightSpeed = 1.0f;
    public float yawSpeed = 250.0f;
    public float pitchSpeed = 250.0f;

    void Update()
        float time = Time.deltaTime;
        float yaw = Input.GetAxis("Mouse X") * yawSpeed * time;
        float pitch = Input.GetAxis("Mouse Y") * pitchSpeed * time;

        transform.Rotate(Vector3.left, -pitch);
        transform.Rotate(Vector3.forward, -yaw);
        transform.Translate(Vector3.forward * flightSpeed * time);

You probably want to change flightSpeed a bit in case you find the motion too slow. It should be attached to a camera. It uses mouse controls to fly sort of like an airplane.

Finally got it working!!! The script is as follows:

screenVec = Vector3(Input.mousePosition.x - ScreenCenter.x, Screen.height - Input.mousePosition.y - ScreenCenter.y, 0);
var tarAngle: float = (Mathf.Atan2(screenVec.y,screenVec.x) * Mathf.Rad2Deg)+90;
if (tarAngle < 0) tarAngle +=360;
var roll:float = Mathf.DeltaAngle(tarAngle , -transform.eulerAngles.z);
if (roll != 0) {
    if (Mathf.Abs(roll) > rollSpeed*Time.deltaTime) roll = rollSpeed*Time.deltaTime*Mathf.Sign(roll);
    transform.RotateAround(transform.position,transform.forward, roll);