Problems limiting object rotation with Mathf.Clamp()

jadkins4 picture jadkins4 · Sep 13, 2014 · Viewed 8.7k times · Source

I am working on a game that rotates an object on the z axis. I need to limit the total rotation to 80 degrees. I tried the following code, but it doesn't work. minAngle = -40.0f and maxAngle = 40.0f

Vector3 pos = transform.position;
pos.z = Mathf.Clamp(pos.z, minAngle, maxAngle);
transform.position = pos;

Answer

Imapler picture Imapler · Sep 16, 2014

The code you posted clamps the z position. What you want is to use transform.rotation

void ClampRotation(float minAngle, float maxAngle, float clampAroundAngle = 0)
{
    //clampAroundAngle is the angle you want the clamp to originate from
    //For example a value of 90, with a min=-45 and max=45, will let the angle go 45 degrees away from 90

    //Adjust to make 0 be right side up
    clampAroundAngle += 180;

    //Get the angle of the z axis and rotate it up side down
    float z = transform.rotation.eulerAngles.z - clampAroundAngle;

    z = WrapAngle(z);

    //Move range to [-180, 180]
    z -= 180;

    //Clamp to desired range
    z = Mathf.Clamp(z, minAngle, maxAngle);

    //Move range back to [0, 360]
    z += 180;

    //Set the angle back to the transform and rotate it back to right side up
    transform.rotation = Quaternion.Euler(transform.rotation.eulerAngles.x, transform.rotation.eulerAngles.y, z + clampAroundAngle);
}

//Make sure angle is within 0,360 range
float WrapAngle(float angle)
{
    //If its negative rotate until its positive
    while (angle < 0)
        angle += 360;

    //If its to positive rotate until within range
    return Mathf.Repeat(angle, 360);
}