using UnityEngine; [RequireComponent(typeof(CharacterController))] public class SimpleFPSController : MonoBehaviour { public Camera playerCamera; public float moveSpeed = 6f; public float mouseSensitivity = 2f; public float gravity = -20f; public float jumpHeight = 1.2f; public float recoilReturnSpeed = 18f; private CharacterController characterController; private float verticalVelocity; private float pitch; private float recoilPitchOffset; private void Awake() { characterController = GetComponent(); if (playerCamera == null) playerCamera = GetComponentInChildren(); } private void Start() { Cursor.lockState = CursorLockMode.Locked; Cursor.visible = false; } private void Update() { Look(); Move(); } public void AddRecoil(float amount) { recoilPitchOffset -= Mathf.Clamp(amount, 0f, 8f); } private void Look() { float mouseX = Input.GetAxis("Mouse X") * mouseSensitivity; float mouseY = Input.GetAxis("Mouse Y") * mouseSensitivity; transform.Rotate(Vector3.up * mouseX); pitch = Mathf.Clamp(pitch - mouseY, -85f, 85f); recoilPitchOffset = Mathf.MoveTowards(recoilPitchOffset, 0f, recoilReturnSpeed * Time.deltaTime); if (playerCamera != null) playerCamera.transform.localRotation = Quaternion.Euler(pitch + recoilPitchOffset, 0f, 0f); } private void Move() { Vector3 input = new Vector3(Input.GetAxisRaw("Horizontal"), 0f, Input.GetAxisRaw("Vertical")); input = Vector3.ClampMagnitude(input, 1f); Vector3 move = transform.TransformDirection(input) * moveSpeed; if (characterController.isGrounded && verticalVelocity < 0f) verticalVelocity = -2f; if (characterController.isGrounded && Input.GetKeyDown(KeyCode.Space)) verticalVelocity = Mathf.Sqrt(jumpHeight * -2f * gravity); verticalVelocity += gravity * Time.deltaTime; move.y = verticalVelocity; characterController.Move(move * Time.deltaTime); } }