Rotation constraints

Hello, is there a way to limit Quaternion rotation, without using eulerAngles? Lets say I’d want to limit Transform’s rotation on Y axis (in 3d space) and between -90 and 90 degrees.
My implementation looks like this, but it works not good. Suffers from gimbal locking.

float minAngle = -90f;
float maxAngle = 90f;

void Update() {
   Vector3 eulerAngles = transform.rotation.eulerAngles;
   eulerAngles.x = 0f;
   eulerAngles.y = Mathf.Clamp(eulerAngles.y, minAngle, maxAngle);
   eulerAngles.z = 0f;
   transform.rotation = Quaternion.Euler(eulerAngles);
}

Declare, adjust and clamp your own float that is the angle, use Quaternion.Euler(x,y,z) to make new rotations.

An example:

Turret aiming/rotating:

NEVER read from the .eulerAngles property. Here is why:

https://starmanta.gitbooks.io/unitytipsredux/content/second-question.html

Thank you so much! That’s the answer I was looking for.

Hi, a new issue arise. When the angle is being min clamped, final rotation stays solid, until target moves to max clamp, where the rotation sometimes just ignores clamps and rotates to the other clamp through rotation which it should not achieve. My implementation look like this:

public Transform target;
public float speed;
public Vector2 clamp;

private void Update()
{
   Vector3 deltaToTarget = target.position - transform.position;
   float angle = Mathf.Atan2(deltaToTarget.x, deltaToTarget.z) * Mathf.Rad2Deg;
   angle = Mathf.Clamp(angle, clamp.x, clamp.y);
   Quaternion traverse = Quaternion.Euler(0f, angle, 0f);
   transform.localRotation = Quaternion.Slerp(transform.localRotation, traverse, speed * Time.deltaTime);
}

I made a gif visualising the issue. Red block represents X axis, Green Y axis and Blue Z axis.
Clamp is set to -100, 100.
grizzledunhappyghostshrimp
Is there a way to prohibit this weird behaviour?

Yes. Do not Slerp / Lerp the rotation.

Instead Lerp the Angle itself… so if angle is clamped at -100 and you keep going around and suddenly angle is 100, you would slide -100 smoothly down to 100 and use that value to continue to produce rotations.