First Person Camera using Character Controller


Click the image to access the demonstration (rotation is very sensitive)

This is incomplete, however below is a script for the FPS character controller shown in the demo above.

Complete First Person Character Controller Script

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.InputSystem;

public class PlayerMovementFPS : MonoBehaviour
{
    // x for l/r, y for f/b
    public Vector2 moveInputVector;
    // x for rotate l/r, y for look u/d
    public Vector2 lookInputVector;

    public Transform lookTransformPoint;

    // Movement and Look Variables
    public float moveSpeed = 25;
    public float turnSpeed = 200;

    public float lookRotateDirection = 0; // Start amount of rotation
    public float maxVerticalLookAngle = 80; // Up down maximum angle to look
    public float lookVerticalDirection = 0; // // Start amount of vertical look rotation

    public float velocity = 0;
    public float gravity = 9.8f;

    public CharacterController characterController;

    void Start() {
        characterController = GetComponent<CharacterController>();
    }

    void OnMove(InputValue iv) {
        moveInputVector = iv.Get<Vector2>();
    }

    void OnLook(InputValue iv) {
        lookInputVector = iv.Get<Vector2>();
    }

    // Update is called once per frame
    void Update()
    {
        // Speed up rotation overtime
        lookRotateDirection += lookInputVector.x;
        // Limit to min and maximum turn speed
        lookRotateDirection = Mathf.Clamp(lookRotateDirection, -turnSpeed, turnSpeed);
        // Rotate the player around the y axis (spin)
        transform.Rotate(0, lookRotateDirection * Time.deltaTime, 0);
        // The longer looking in a direction the greater the value move in that direction
        lookVerticalDirection += lookInputVector.y;
        // Limit the min and max angles to be able to look vertically
        lookVerticalDirection = Mathf.Clamp(lookVerticalDirection, -maxVerticalLookAngle, maxVerticalLookAngle);
        // Rotate the player view to look up and down
        lookTransformPoint.localRotation = Quaternion.Euler(-lookVerticalDirection, 0, 0);

        // Get forward and right in relation to the player
        Vector3 forward = transform.TransformDirection(Vector3.forward);
        Vector3 right = transform.TransformDirection(Vector3.right);
        // Forward and back speed of the player
        float curSpeed = moveSpeed * moveInputVector.y * Time.deltaTime;
        // Strafe speed of the player
        float strafeSpeed = moveSpeed * moveInputVector.x * Time.deltaTime;
        // Move the player
        characterController.Move(forward * curSpeed + right * strafeSpeed);

        // If on the ground set velocity to 0 as not falling
        if(characterController.isGrounded)
        {
            velocity = 0;
        }
        else // not on the ground to have negative velocity increase by gravity over time to cause to fall.
        {
            velocity -= gravity * Time.deltaTime;
            characterController.Move(new Vector3(0, velocity, 0));
        }
    }
}