Search code examples
objectunity-game-enginerotationclamp

Problems limiting object rotation with Mathf.Clamp()


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;

Solution

  • 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);
    }