Sean Chambers
Sean Chambers

Reputation: 41

Can't Get My Camera To Limit Its Rotation Properly

In my game, I want to clamp the player's camera so it can't do frontflips or backflips. I want to clamp the x-axis between -75 and 50 but it just won't work.

Every time I add a clamp such as the one in my code, the camera doesn't want to move it's rotation from 0,0,0 farther than Input.GetAxisRaw says the mouse is moving.

I've tried using if statements as manual clamps too but it either stays at 0,0,0 constantly or -75,0,0 constantly if I switch the polarity.

I've tried replacing the camera in case it was something related to its settings but nothing changes.

I didn't want to post this because it shouldn't be this hard but I've spent multiple days on this and I'm out of options; any and all ideas are much appreciated.

I am using Visual Studio as my editor.

using UnityEngine;

public class PlayerMove : MonoBehaviour {

    Rigidbody rb;

    public Camera cam;
    public Transform camTrans;

    Vector3 movement;
    Vector3 rotation;

    public float sensitivityX;
    public float sensitivityY;
    public float playerSpeed;
    public float jumpForce;
    float forward;
    float sideways;

    void Start()
    {
        rb = GetComponent<Rigidbody>();
    }

    void FixedUpdate ()
    {
        forward = Input.GetAxisRaw("Vertical");
        sideways = Input.GetAxisRaw("Horizontal");
        movement = new Vector3 (forward, 0, -sideways).normalized;

        float _xRot = Input.GetAxisRaw("Mouse Y");
        float _yRot = Input.GetAxisRaw("Mouse X");

        rotation = new Vector3(0f, _yRot, 0f) * sensitivityX;

        float _jump = Input.GetAxisRaw("Jump");

        if (movement != Vector3.zero)
        {
            MovePlayer();
        }
        if (rotation != Vector3.zero && Input.GetAxisRaw("Fire2") != 0 || _xRot != 0 && Input.GetAxisRaw("Fire2") != 0)
        {
            Rotate(-_xRot);
        }
        if (_jump != 0f)
        {
            Jump();
        }
    }

    void MovePlayer()
    {
        float _playerSpeed;
        _playerSpeed = playerSpeed * 0.1f;
        transform.Translate(movement * _playerSpeed * Time.fixedDeltaTime, Space.Self);
    }

    void Jump()
    {
        if (IsGrounded())
        {
            rb.AddForce(new Vector3(0, 1 * jumpForce, 0), ForceMode.Impulse);
        }
    }

    void Rotate(float _camRot)
    {
        camTrans.Rotate(new Vector3(_camRot * sensitivityY, 0, 0));
        float _camPosX = camTrans.rotation.x;
        Mathf.Clamp(_camPosX, -75, 50);
        camTrans.rotation = Quaternion.Euler(new Vector3(_camPosX, 0, 0));
        rb.MoveRotation(rb.rotation * Quaternion.Euler(rotation * sensitivityX));
    }

    bool IsGrounded()
    {
        RaycastHit hit;
        return Physics.Raycast(transform.position, Vector3.down, out hit, 1.001f);
    }
}

Upvotes: 2

Views: 173

Answers (1)

Ehsan Mohammadi
Ehsan Mohammadi

Reputation: 1228

Input.GetAxisRaw("Mouse Y"); returns the number of units the mouse moved (See Unity Documentation - Input.GetAxisRaw).

When you move your mouse, the script works, but because void Rotate() called each frame in Update() function, after some frames Input.GetAxisRaw("Mouse Y"); returns 0 and then _camRot = 0.

So, camTrans.rotation = Quaternion.Euler(new Vector3(0, 0, 0)); and because Update() called multiple times per second, We think camera stays at 0,0,0 constantly.

To clamp the rotation, you can change your code to this:

public class PlayerMove : MonoBehaviour 
{
    ...

    private float rotationX;

    ...

    void Rotate(float _camRot)
    {
        rotationX += _camRot * sensitivityY;
        rotationX = Mathf.Clamp(rotationX, -75, 50);
        camTrans.localEulerAngles = new Vector3(rotationX, camTrans.localEulerAngles.y, camTrans.localEulerAngles.z);

        rb.MoveRotation(rb.rotation * Quaternion.Euler(rotation * sensitivityX));
    }
}

I hope it helps you.

Upvotes: 1

Related Questions