[SOLVED] How to clamp Camera rotation on the X Axis - FPS controller

Hi all,

Have been trying for hours to crack this, and can’t seem to make reasonable headway.
I’m making a first person shooter and want to restrict how far the player can look up or down - as it is the player can rotate forever on the X-axis, as if he were somersaulting.
I’ve been attempting different things with the MathF.Clamp method and Quaternion.Euler() but to no avail.

the script is attached to a Capsule, and the Camera is a child of the capsule.
Here is my current code to move the player:

public class InputManager : MonoBehaviour {

  

    //Here I declare the speed of movement and speed of rotation
    public float speed = 1f;
    public float RotSpeed = 6f;
    //Here I declare two gameobjects which I've assigned in the inspector
    public GameObject Camera;
    public GameObject PauseMenu;
    public GameObject Player;
    //this boolean to to tell if game should be paused or not
    public static bool GamePaused;
    //Boolean to detect if player is grounded
    public bool Grounded;
    //movement forward-backwards
    float MoveFB;
    //movement left-right
    float MoveLR;
    //rotation on x and y axis
    float rotX;
    float rotY;

void Update () {
        //first declare a float to hold the value of the virtual axis
        //and multiply it by the speed
        if (GamePaused == false)
        {

        MoveFB = Input.GetAxis ("Vertical")*speed;
        //use transform.translate to then move the player along that axis
        //at that speed
        transform.Translate (0, 0, MoveFB);
        MoveLR = Input.GetAxis ("Horizontal") * speed;
        transform.Translate(MoveLR,0,0);

        //now for the mouse rotation
        rotX = Input.GetAxis("Mouse X")*RotSpeed;
        rotY = Input.GetAxis ("Mouse Y")*RotSpeed;
       
         

        //Camera rotation only allowed if game us not paused
            Camera.transform.Rotate(-rotY, 0, 0);
            transform.Rotate(0, rotX, 0);

        }

I’ve also tried attaching a script to the camera object and restricting it’s movement in this way:

  private float InputX;
    private float InputY;
    private float Yrotation;
    private float Xrotation;
    public float RotationSpeed = 7f;
    private GameObject Camera;
    // Use this for initialization
    void Start () {
        Camera = this.gameObject;
    }
   
    // Update is called once per frame
    void Update () {
        InputX = Input.GetAxis("Mouse X")*RotationSpeed;
        InputY = Input.GetAxis("Mouse Y")*RotationSpeed;
       // Yrotation = InputY;
        Yrotation += InputY;
        Xrotation += InputX;
        Yrotation = Mathf.Clamp(Yrotation, -90f, 90f);
        transform.rotation = Quaternion.Euler(-Yrotation, transform.parent.rotation.y,
            transform.parent.rotation.z);
       // transform.parent.Rotate(0f, Xrotation, 0f);

This restricted the camera’s axis exactly how I wanted but kept snapping it’s orientation to the back of the player’s head, and no rotation on the Y axis was possible.

Any advice you might have on restricting the camera on the x axis is greatly appreciated :slight_smile:

Simple way is to store your own values and rebuild your rotations every frame rather than accumulating them as you’re doing now.

        //now for the mouse rotation
        rotX += Input.GetAxis("Mouse X")*RotSpeed;
        rotY += Input.GetAxis ("Mouse Y")*RotSpeed;

   rotY = Mathf.Clamp(rotY, -90f, 90f);       

        //Camera rotation only allowed if game us not paused
   Camera.transform.rotation = Quaternion.Euler(-rotY, 0f, 0f);
   transform.rotation = Quaternion.Euler(0f, rotX, 0f);
8 Likes

Muchas Gracias my friend, really helped me out :slight_smile:
It was still locking the camera’s orientation to look out the back of the player’s head, but restricted the X axis movement perfectly (seems to be I had to access the local rotation)
So I added the local rotation to your code and now it seems to work stellar:

            rotX += Input.GetAxis("Mouse X")*RotSpeed;
            rotY += Input.GetAxis("Mouse Y") * RotSpeed;
            rotY = Mathf.Clamp(rotY, -90f, 90f);
            Camera.transform.localRotation = Quaternion.Euler(-rotY, 0f, 0f);
            transform.rotation = Quaternion.Euler(0f, rotX, 0f);

Thanks again for the help mate!

3 Likes

I saw this on github somewhere. “Hippity Hoppity your code is now my property”

Thanks friend.

Here is a Easy way of clamping camera rotation

1 Like

Hi guys how do I make my camera move in the Joystick

Thanks! it came in handy

If you want to be finicky, but technically correct, use rotX = (rotX + Input.GetAxis("Mouse X")*RotSpeed)%360 and rotY = (rotY + Input.GetAxis ("Mouse Y")*RotSpeed)%360 to prevent over/underflow.