Limit Rotation Issues

Hello! So I created a simple script that rotates an object around the y axis when you hold down the “A” or “D” keys on the keyboard. With “A” going one direction and “D” going another. I have tried multiple ways to limit the rotation range. My desired range is 0-180 degrees. However nothing I do seems to work.


In this latest attempt I use a clamp to try and clamp the limits. I believe I have figured out what is going on but I don’t know how to fix it. When my rotation exceeds 180 it sometimes becomes a negative number. And when my rotation goes under 0, instead of becoming a negative number, it becomes positive!


For example, if I rotate negatively towards 0, it will actually become a big number and then jump to the max side of the clamp: 180. There seems to be some weird stuff that happens when you hit 0 and 180. I tried to mitigate this by clamping between 1 - 179. This seemed to work! However if I rotate by anything other than 1 degree the issue comes back because it is not evenly landing on 1 and 179.


Does anyone know how I can fix this. I just want a clean limit of 0-180, and I want to be able to rotate by any amount I want and have it stop when it hits that number! Maybe I need a lerp? Or a time function?

Here is my code for reference:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class rotator : MonoBehaviour
{
    private float yRotation;
    private float rotationSpeed;
    private Vector3 currentRotation;


    // Start is called before the first frame update
    void Start()
    {
        yRotation = this.transform.localEulerAngles.y;
        rotationSpeed = 1.0f;

}

    // Update is called once per frame
    void Update()
    {

        //Holding down "D" key.
        if (Input.GetKey(KeyCode.D))
        {
           
                this.transform.localEulerAngles -= new Vector3(0, rotationSpeed, 0);
            
        }

        //Holding down "A" key.
        else if (Input.GetKey(KeyCode.A))
        {
        
                this.transform.localEulerAngles += new Vector3(0, rotationSpeed, 0);
            

        }
        currentRotation = transform.localRotation.eulerAngles;
        currentRotation.y = Mathf.Clamp(currentRotation.y, 1f, 179.0f);
        transform.localRotation = Quaternion.Euler(currentRotation);
    }
}

Rotations in Unity are performed using Quaternions and can then be reconstructed into Euler angle approximations thereafter. Being able to set the rotation using them, while convenient, isn’t inherently the best approach to doing so.

With that in mind, you can replace the rotation scheme you’re currently using with one that focuses on Quaternion.AngleAxis() instead.

public float rotationSpeed = 90f; // ex. 90 degrees per second

void Update()
{
	if(Input.GetKey(KeyCode.A))
	{
		// Counter-clockwise example
		yRotation -= Time.deltaTime * rotationSpeed;
	}
	if(Input.GetKey(KeyCode.D))
	{
		// Clockwise example
		yRotation += Time.deltaTime * rotationSpeed;
	}
	yRotation = Mathf.Clamp(yRotation, 0f, 180f);
	transform.rotation = Quaternion.AngleAxis(yRotation, Vector3.up);
}