The camera can't go up and down!

Hi,
I’m trying to create a very basic fps game in unity. Unfortunately I have encountered a problem which is that my character’s camera can’t look up. Whenever I try to go up and down with my mouse, it feels like the vision is stuck. I have a video of what happens when I experimented to show the problem. Here is the link:

Im almost sure that my problem comes from a coding mistake. Can y’all help me?

my Input Manager class

public class InputManager : MonoBehaviour
{
    private PlayerInput playerInput;
    private PlayerInput.OnFootActions OnFoot;

    private PlayerMotor motor;

    private PlayerLook look;

    // Start is called before the first frame update
    void Awake()
    {
        playerInput = new PlayerInput();
        OnFoot = playerInput.OnFoot;
        motor = GetComponent<PlayerMotor>();
        look = GetComponent<PlayerLook>();
        // ctx = callback context to call the jump fct
        OnFoot.Jump.performed += ctx => motor.Jump();
    }

    // Update is called once per frame
    void FixedUpdate()
    {
        motor.ProcessMove(OnFoot.Movement.ReadValue<Vector2>());
    }

    void LateUpdate()
    {
        look.ProcessLook(OnFoot.Look.ReadValue<Vector2>());
    }

    private void OnEnable()
    {
        OnFoot.Enable();
    }
    private void OnDisable()
    {
        OnFoot.Disable();
    }
}

My Player Look class

public class PlayerLook : MonoBehaviour
{

    public Camera cam;
    private float xRotation = 0f;

    public float xSensitivity = 30f;
    public float ySensitivity = 30f;

    public void ProcessLook (Vector2 input)
    {
        float mouseX = input.x;
        float mouseY = input.y;

        xRotation = (mouseY * Time.deltaTime) * ySensitivity;
        xRotation = Mathf.Clamp(xRotation, -120f, 120f);

        cam.transform.localRotation = Quaternion.Euler(xRotation, 0, 0);

        transform.Rotate(Vector3.up * (mouseX * Time.deltaTime) * xSensitivity);
    }
}

My Player Motor class

public class PlayerMotor : MonoBehaviour
{

    private CharacterController controller;
    private Vector3 playerVelocity;
    private float speed = 5f;
    private bool isGrounded;
    public float gravity = -9.8f;
    public float jumpHeight = 5f;

    // Start is called before the first frame update
    void Start()
    {
        controller = GetComponent<CharacterController>();
    }

    // Update is called once per frame
    void Update()
    {
        isGrounded = controller.isGrounded;
    }
    //receive input from input manager script and apply them to
    //  our character
    public void ProcessMove(Vector2 input)
    {
        Vector3 moveDirection = Vector3.zero;
        moveDirection.x = input.x;
        moveDirection.z = input.y;
        controller.Move(transform.TransformDirection(moveDirection) *  speed * Time.deltaTime);
        playerVelocity.y += gravity * Time.deltaTime;
        controller.Move(playerVelocity * Time.deltaTime);
        if(isGrounded && playerVelocity.y < 0)
        {
            playerVelocity.y = -3f;
        }
    }

    public void Jump()
    {
        if(isGrounded)
        {
            playerVelocity.y = Mathf.Sqrt(jumpHeight * -4.0f * gravity);
        }
    }
}

You probably want to toss this code out because it is based on defective example code that calls .Move() twice per frame. Because of this it may cause you random ground detection problems.

9123727--1266184--Screen Shot 2023-07-04 at 8.07.02 AM.png

CharacterController CharMover broken:

I wrote about this before: the Unity example code in the API no longer jumps reliably.

If you call .Move() twice in one single frame, the grounded check may fail.

I reported it to Unity via their docs feedback in October 2020. Apparently it is still broken:

Here is a work-around:

I recommend you also go to that same documentation page and ALSO report that the code is broken.

When you report it, you are welcome to link the above workaround. One day the docs might get fixed.

If you would prefer something more full-featured here is a super-basic starter prototype FPS based on Character Controller (BasicFPCC):

That one has run, walk, jump, slide, crouch… it’s crazy-nutty!!

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
   
   
public class PlayerLook : MonoBehaviour
{
   
    public Camera cam;
    private float xRotation = 0f;
   
    public float xSensitivity = 10f;
    public float ySensitivity = 10f;
   

    public void ProcessLook (Vector2 input)
    {
        float mouseX = input.x;
        float mouseY = input.y;
   
        //xRotation = (mouseY * Time.deltaTime) * ySensitivity;   // This was incorrect.
        xRotation += mouseY * ySensitivity; // mouseY should be added to xRotation
        // There's also no need to use Time.deltaTime because the mouse isn't effected by frame rate

        xRotation = Mathf.Clamp(xRotation, -80f, 80f);
   
        cam.transform.localRotation = Quaternion.Euler(xRotation, 0, 0);  
   
        transform.Rotate(Vector3.up * mouseX * xSensitivity);
    }
}