Transform Z axis rotation from center of screen toward mouse cursor with Quaternion.LookRotation for a top down game.

I’m trying to get a plane to rotate on its Z axis only for a 2D top down shooter concept. I finished the Evac City tutorial and now am rewriting the code so that the games horizontal and vertical axes are X & Y (rather than X & Z like in the tutorial).

Here is my code that does not rotate the player sprite at all:

	void Update () {
		
		FindInput();
		ProcessMovement();
		
		if (thisIsPlayer == true) {
			HandleCamera();
		}
	}
	void FindPlayerInput () {
		
		// find vector to move
		inputMovement = new Vector3( Input.GetAxis("Horizontal"),Input.GetAxis("Vertical"),0 );
		
		tempVector2 = new Vector3(Screen.width * 0.5f,Screen.height * 0.5f,0);
		tempVector = Input.mousePosition;
		
		tempVector.z = 0;
		
		inputRotation = tempVector - tempVector2;
	}
	
	void ProcessMovement () {
		rigidbody.AddForce( inputMovement.normalized * moveSpeed * Time.deltaTime );
		transform.rotation = Quaternion.LookRotation(inputRotation);
		transform.eulerAngles = new Vector3(0,0,transform.eulerAngles.z);
		transform.position = new Vector3(transform.position.x,transform.position.y,0);
	}

I’ve been stuck on this for about 8 hours of coming back to it and I’m losing my mind. The code in the tutorial (see below) works perfectly fine, all I am doing is leaving the Z axis perpendicular to the camera instead of swappying Z with Y like the tutorial shows.

Here is the tutorial code:

	void Update () {
		
		FindInput();
		ProcessMovement();

		if (thisIsPlayer == true) {
			HandleCamera();
		}
	}
	void FindPlayerInput () {
		
		// find vector to move
		inputMovement = new Vector3( Input.GetAxis("Horizontal"),0,Input.GetAxis("Vertical") );
		
		// find vector to the mouse cursor / the position of the middle of the screen
		tempVector2 = new Vector3(Screen.width * 0.5f,0,Screen.height * 0.5f);
		
		// find the position of the mouse cursor on screen
		tempVector = Input.mousePosition;
		
		// input mouse position gives us 2D coordinates, moving Y coordinate to the Z coordinate in tempVector and setting the Y coordinate to 0 so the Vector will read the input along the X and Z axes (instead of X and Y)
		tempVector.z = tempVector.y;
		tempVector.y = 0;
		
		// the direction to face/aim/shoot is from the middle of the screen to the mouse cursor
		inputRotation = tempVector - tempVector2;
	}
	void ProcessMovement () {
		
		rigidbody.AddForce (inputMovement.normalized * moveSpeed * Time.deltaTime);
		transform.rotation = Quaternion.LookRotation(inputRotation);
		transform.eulerAngles = new Vector3(0,transform.eulerAngles.y + 180,0);
		transform.position = new Vector3(transform.position.x,0,transform.position.z);
	}

Am I missing something about the world space in relation to the local space of the Player game object?

The line in the original code about trans.eulerAngles = (0,trans.eulerAngles.y + 180,0); doesn’t seem to do anything useful (it works fine w/o it.) And it breaks a rule from the docs. They say not to try to set just one eulerAngle. They all sort of interrelate.

It seems like you can make the Quaternion.LookRotation(inputRotation) work properly in the first place. The second optional input is the “up” position. For a top-down, you want up to be up, so they left it out. For a side view like you want, up should be towards you. Away is +Z, towards is -Z, so: Q.LR(inpRot, -Vector3.forwards). That seemed to work for me.

If you have to do a 180, seems easier to flip the inputs, such as tVec.y = SCreen.Height-tVec.y;.

The line trans.eulerAngles = (0,trans.eulerAngles.y + 180,0); was only used in the tutorial. Because of the way the author decided to render the sprite onto the plane he needed the flip it on the y axis. I am choosing not to follow the tutorial exactly after completing it once already

I changed the ProcessMovement function to include the argument for the “up” position:

		tempVector2 = new Vector3(Screen.width * 0.5f,Screen.height * 0.5f,0);
		tempVector = Input.mousePosition;
		
		tempVector.z = 0;
		
		inputRotation = tempVector - tempVector2;

		transform.rotation = Quaternion.LookRotation(inputRotation,Vector3.forward);
		transform.eulerAngles = new Vector3(0,0,transform.eulerAngles.z);

Without the ‘transform.eulerAngles’ the plane finally rotates! However, the plane also rotates 90 degrees on its local x axis and stays fixed while it spins on its local y axis to follow the mouse. I am trying to get it to rotate on its z axis only.

When I use ‘transform.eulerAngles’ it only rotates on its z axis while snapping in 90 degree increments, and only rotating to 270, 0 and 90 degrees.

I’m still struggling to understand what is occurring with this code, but I’m determined to understand it, even if there is a better solution I still want to learn why this code is doing what it’s doing.