Trouble with Camera Rotation Math

Hello everyone, I’ve got a setup where the player (with a “analog stick”) can rotate a camera around an object spherically (actually, the camera is anchored to another GameObject, and the GO rotates and takes the camera with it). My problem is that while I can get the up/down or left/right rotation to work, when I try to use both at the same time or one after another, the rotation gets “wobbly” and becomes increasingly incorrect.

My Method:

My thought was that I would “just” create the rotation for desired left/right and for desired up/down, then add them together, then add that to the current rotation. I’m not really sure which part of this is flawed (if not the entire idea), but any guidance is appreciated.

	public void RotateCamera(Vector2 horizVert)
	{
		//up and down:
		vertQ = Quaternion.Euler ( transform.right * ( (maxRotationSpeed * horizVert.y) * Time.deltaTime) );
		//verticalV = vertQ.eulerAngles;

		//left and right:
		horizQ = Quaternion.Euler ( Vector3.up * ( (maxRotationSpeed * horizVert.x) * Time.deltaTime) );
		//horizontalV = horizQ.eulerAngles;

		transform.rotation *= (vertQ * horizQ);
	}

Any thoughts are appreciated, thank you for reading.

I built something similar (but kind of opposite) from the MouseOrbit script in the Unity standard assets.

Really the big clue there is that keeping a hard value for cumulative X and Y rotation during runtime (in my code below, that’s _cameraXRotation and _cameraYRotation) and rebuilding your rotation from scratch each time should do what you want. Try this little guy. I assume horizVert is just Input.GetAxis on your controller axes.

	void ApplyCameraRotationController(Vector2 horizVert) {
		_cameraXRotation = _cameraXRotation + horizVert.x * maxRotationSpeed * Time.deltaTime;
		_cameraYRotation = _cameraYRotation + horizVert.y * maxRotationSpeed * Time.deltaTime;
		transform.rotation = Quaternion.Euler(_cameraYRotation, _cameraXRotation, 0);
	}

I suspect the issue is that you are adjusting rotations around particular world axis (Quaternion.Euler). However, once you have rotated a bit on both axis, the WORLD axis is no longer what you want to rotate about: you want to rotate about the OBJECT’S current axis.

Take a look at using this function to modify your transforms rotation instead:

Note that it has the option to rotate about a specified world space, or local space, axis. (default is local, which is what you want, I think)

EDIT: I think I’m going to delete this answer, i see now you ARE applying the rotation to the local object with *=