Clamping Rotation

Hello. I’m having issues clamping my rotation of my gameObject.

I’ve tried using Mathf.Clamp but doesn’t seem to be working correctly.

I read I needed to cache the pos of the object and then clamp it and then apply it.

Am I on the right track with this?

public class Drag : MonoBehaviour
{
    public float rotSpeed = 20f;

    public float xMin;
    public float xMax;

    void OnMouseDrag()
    {
        float rotX = Input.GetAxis("Mouse X")*rotSpeed;


        transform.Rotate(Vector3.up, -rotX);

      

        //transform.rotation = Quaternion.Euler(0, -rotX, 0);

    }


}

“Clamping a rotation” is vague. Could you be more precise?
Generally a rotation involves an angle and an axis to rotate about. Do you want the axis to be fixed and clamp only the angle? or do you want the axis to be also free? In this last case the rotation is constrained within a cone.

Sorry, basically I’ve got a cube in front of me. Click and drag it left and right. It works but I need to clamp how far it can rotate left and right, so it can only rotate between a range.

So far I’ve tried this, but I just can’t seem to use Mathf.Clamp correctly to achieve what I want.

public class Drag : MonoBehaviour
{
    public float rotSpeed = 20f;

    public float xMin;
    public float xMax;

    void OnMouseDrag()
    {
        float rotX = Input.GetAxis("Mouse X")*rotSpeed;

        var ClampedAxis = new Vector3(0, Mathf.Clamp(transform.rotation.y, -45, 45), 0);

        transform.Rotate(ClampedAxis, -rotX);

      


    }


}

Your code clamps the axes around which you’re rotating, not the amount of rotation.

Maybe that’s what you want:

    float angle = 0.0f;

    void OnMouseDrag()
    {
        angle += Input.GetAxis("Mouse X") * rotSpeed*Time.deltaTime;
        angle = Mathf.Clamp(angle, -45.0f, 45.0f);
        transform.rotation = Quaternion.Euler(0.0f, angle, 0.0f);
    }
1 Like

@ericbegue That’s exactly what I was looking for. I don’t know how I messed that up…

Thanks Eric!

Also I noticed my issue with angle = Input.GetAxis(“Mouse X”) as opposed to +=. So I guess it wasn’t incrementing the angle right?

With this code,

        float rotX = Input.GetAxis("Mouse X")*rotSpeed;
        transform.Rotate(Vector3.up, -rotX);

It was incrementing the angle through transform.Rotate(…), though indirectly (or under the hood).
Here rotX is a delta angle, which you don’t want to clamp. What you want to clamp is the current angular position, but here that is not apparent.

The second trial, with clamping the axis, simply does not make sens.

Though using transform.Rotate, you could have got it right with the following code:

    void OnMouseDrag()
    {
        // Rotate
        float deltaAngle = Input.GetAxis("Mouse X") * rotSpeed * Time.deltaTime;
        transform.Rotate(new Vector3(0.0f, deltaAngle, 0.0f));

        // Clamp
        float angle = transform.rotation.eulerAngles.y;
        angle = Mathf.Clamp(angle, -45.0f, 45.0f);
        transform.rotation = Quaternion.Euler(0.0f, angle, 0.0f);
    }

It gives the same result, but it is more verbose. That’s why I made a new variable (float angle) instead, that keeps track of the current angular position.

Do you understand where your mistake was or is there something still not quiet clear?