How do I uniquely clamp a rotation for each axis?

I’m attempting to create a security camera that tracks the player. However, it can only track the player within a specific pitch, heading, and roll limit, where the range is +/- 180-degrees. The below works as intended when the object’s rotation is {0,0,0}. But when I change the heading, the security camera clamps as though its rotation was still {0,0,0}. How do I uniquely clamp a rotation for each axis and still allow the object to be rotated?

void FixedUpdate()
{
	// Where 'Pivot' is a child object of the current object

	GameObject target = GameObject.FindGameObjectWithTag("Player");
	Vector3 direction = (target.collider.bounds.center - Pivot.transform.position).normalized;
	direction = Vector3.RotateTowards(Pivot.transform.forward, direction, Mathf.Deg2Rad * RotationSpeed * Time.fixedDeltaTime, 0f);

	Vector3 eulerRotation = Quaternion.LookRotation(direction).eulerAngles;
	if (eulerRotation.x > 180f)
	{
		eulerRotation.x -= 360f;
	}
	if (eulerRotation.y > 180f)
	{
		eulerRotation.y -= 360f;
	}
	if (eulerRotation.z > 180f)
	{
		eulerRotation.z -= 360f;
	}

	eulerRotation = new Vector3(
		Mathf.Clamp(eulerRotation.x, MinPitch, MaxPitch),
		Mathf.Clamp(eulerRotation.y, MinHeading, MaxHeading),
		Mathf.Clamp(eulerRotation.z, MinRoll, MaxRoll)
	);
	Pivot.transform.rotation = Quaternion.Euler(eulerRotation);
}

Cams don’t roll, why do you allow that? it only makes possible gimbal locks worse.

Ither things I noticed:

  • You search for the player in every FixedUpdate. It’s recommended to only do it in Start or directly link the Player in a public member.

  • There are multiple EulerAngles that can represent the same Quaternion and as soon as you set it, it’S stored as a Quaternion, so when you want to get it out again, you may find that your angles are now out of bound, even when they were in bound when you put them in.

If you really want to simulate a cam, you only have two degrees of freedom. Rotation around y and x. And then you don’t have any advantages to use Quaternions. Just store your pitch and yaw and only create the Quaternion when you need to set the rotation.