using Unity.VisualScripting; using UnityEngine; public class FirstPersonController : MonoBehaviour { [Header("Movement Settings")] public float walkSpeed = 50f; // Boosted from 8f to overcome collision issues public float runSpeed = 80f; // Boosted from 14f public float jumpHeight = 2.5f; public float gravity = -20f; [Header("Mouse Look Settings")] public float mouseSensitivity = 3f; public float maxLookAngle = 90f; [Header("References")] public Camera playerCamera; // Private variables private CharacterController controller; private Vector3 velocity; private bool isGrounded; private float xRotation = 0f; void Start() { Debug.Log("Starting game"); // FORCE NORMAL TIME (in case something external changed it) Time.timeScale = 1f; controller = GetComponent(); if (controller == null) { Debug.LogError("FirstPersonController: No CharacterController found!"); return; } if (playerCamera == null) playerCamera = GetComponentInChildren(); Cursor.lockState = CursorLockMode.Locked; Cursor.visible = false; } void Update() { if( controller == null ) return; isGrounded = controller.isGrounded; if (isGrounded && velocity.y < 0) velocity.y = -2f; // ─── Movement via direct KeyCode ─── float moveX = 0f; float moveZ = 0f; if (Input.GetKey(KeyCode.W) || Input.GetKey(KeyCode.UpArrow)) moveZ += 1f; if (Input.GetKey(KeyCode.S) || Input.GetKey(KeyCode.DownArrow)) moveZ -= 1f; if (Input.GetKey(KeyCode.A) || Input.GetKey(KeyCode.LeftArrow)) moveX -= 1f; if (Input.GetKey(KeyCode.D) || Input.GetKey(KeyCode.RightArrow)) moveX += 1f; // DEBUG: Log once when W is first pressed if (Input.GetKeyDown(KeyCode.W)) { Debug.Log($"[FPC DEBUG] W pressed | controller.enabled={controller.enabled} | position={transform.position} | isGrounded={isGrounded}"); Debug.Log($"[FPC DEBUG] Time.timeScale={Time.timeScale} | Time.deltaTime={Time.deltaTime} | walkSpeed={walkSpeed}"); } Vector3 move = transform.right * moveX + transform.forward * moveZ; if (move.magnitude > 1f) move.Normalize(); float currentSpeed = Input.GetKey(KeyCode.LeftShift) ? runSpeed : walkSpeed; Vector3 posBefore = transform.position; controller.Move(move * currentSpeed * Time.deltaTime); // DEBUG: Log if we tried to move but didn't if (move.magnitude > 0f && Input.GetKeyDown(KeyCode.W)) { Vector3 posAfter = transform.position; //Debug.Log($"[FPC DEBUG] Move attempt: delta={move * currentSpeed * Time.deltaTime} | actualDelta={(posAfter - posBefore)} | controller.height={controller.height} | controller.radius={controller.radius}"); // Check what we're colliding with Collider[] nearbyColliders = Physics.OverlapSphere(transform.position, controller.radius + 0.5f); //Debug.Log($"[FPC DEBUG] Found {nearbyColliders.Length} colliders near player"); foreach (Collider col in nearbyColliders) { if (col != controller && !(col is CharacterController)) Debug.LogWarning($"[FPC DEBUG] Nearby collider: {col.gameObject.name} on layer {LayerMask.LayerToName(col.gameObject.layer)}"); } } // Jumping if (Input.GetKey(KeyCode.Space) && isGrounded) velocity.y = Mathf.Sqrt(jumpHeight * -2f * gravity); // Gravity velocity.y += gravity * Time.deltaTime; controller.Move(velocity * Time.deltaTime); // Mouse look HandleMouseLook(); // Escape to unlock cursor if (Input.GetKeyDown(KeyCode.Escape)) { Cursor.lockState = CursorLockMode.None; Cursor.visible = true; } // Click to re-lock cursor if (Input.GetMouseButtonDown(0) && Cursor.lockState == CursorLockMode.None) { Cursor.lockState = CursorLockMode.Locked; Cursor.visible = false; } } void HandleMouseLook() { float mouseX = Input.GetAxis("Mouse X") * mouseSensitivity; float mouseY = Input.GetAxis("Mouse Y") * mouseSensitivity; xRotation -= mouseY; xRotation = Mathf.Clamp(xRotation, -maxLookAngle, maxLookAngle); playerCamera.transform.localRotation = Quaternion.Euler(xRotation, 0f, 0f); transform.Rotate(Vector3.up * mouseX); } }