using UnityEngine; using UnityEngine.InputSystem; [RequireComponent(typeof(CharacterController))] public class FPSController : MonoBehaviour { [Header("References")] [SerializeField] private CharacterController characterController; [SerializeField] private Transform playerBody; [SerializeField] private Camera mainCamera; [Space] [Header("Player Movement")] [SerializeField] private float walkSpeed; [SerializeField] private float sprintSpeed; [SerializeField] private float jumpHeight; [Space] [Header("Gravity Settings")] [SerializeField] private float gravity; [Space] [Header("Ground Check Settings")] [SerializeField] private float groundCheckRadius; [SerializeField] private float groundCheckDistance; [SerializeField] private LayerMask groundLayer; [Space] [Header("Bools")] [SerializeField] private bool isGrounded; [Space] [Header("Input Action References")] [SerializeField] private InputActionReference moveAction; [SerializeField] private InputActionReference sprintAction; [SerializeField] private InputActionReference jumpAction; private Vector2 currentInput; private Vector3 moveDirection; private Vector3 velocity; private void Start() { Cursor.lockState = CursorLockMode.Locked; Cursor.visible = false; } private void Update() { HandleInput(); HandleMovement(); HandlePlayerRotation(); HandleGravity(); HandleGroundCheck(); HandleJump(); } private void HandleInput() { currentInput = moveAction.action.ReadValue<Vector2>(); moveDirection = new Vector3(currentInput.x, 0, currentInput.y); } private void HandleMovement() { Vector3 cameraForward = mainCamera.transform.forward; Vector3 cameraRight = mainCamera.transform.right; cameraForward.y = 0; cameraRight.y = 0; cameraForward.Normalize(); cameraRight.Normalize(); moveDirection = cameraForward * currentInput.y + cameraRight * currentInput.x; bool isSprinting = sprintAction.action.IsPressed(); float currentSpeed = isSprinting ? sprintSpeed : walkSpeed; // = If Sprinting is true ? ( Use Sprint Speed ) : If False Use Walk Speed; var moveVel = Time.deltaTime * currentSpeed * moveDirection; var gravityVel = Time.deltaTime * velocity; characterController.Move(moveVel + gravityVel); } private void HandlePlayerRotation() { playerBody.rotation = Quaternion.Euler(0f, mainCamera.transform.eulerAngles.y, 0f); } private void HandleJump() { if (jumpAction.action.WasPerformedThisFrame() && isGrounded) { velocity.y = Mathf.Sqrt(jumpHeight * -2f * gravity); } } private void HandleGravity() { velocity.y += gravity * Time.deltaTime; } private void HandleGroundCheck() { RaycastHit hit; isGrounded = Physics.SphereCast(transform.position, groundCheckRadius, Vector3.down, out hit, groundCheckDistance, groundLayer); if(isGrounded && velocity.y < 0) { velocity.y = -2f; } } private void OnDrawGizmos() { if (!Application.isPlaying) return; Gizmos.color = Color.blue; Vector3 origin = transform.position; Vector3 direction = Vector3.down; Gizmos.DrawWireSphere(origin + direction * groundCheckDistance, groundCheckRadius); } private void OnEnable() { moveAction.action.Enable(); sprintAction.action.Enable(); jumpAction.action.Enable(); } }