using UnityEngine; using UnityEngine.InputSystem; public class PlayerController : MonoBehaviour { [Header("Movement")] public float moveSpeed = 5f; public float gravity = -9.81f; // Standard Earth gravity public float jumpHeight = 1.0f; // Optional, set to 0 if no jumping allowed [Header("Look Settings")] public float mouseSensitivity = 10f; public float maxLookAngle = 70f; [Header("Interaction")] public float interactionDistance = 3f; public LayerMask interactionLayer; // Components private CharacterController controller; private Transform cameraTransform; // State private float verticalRotation = 0f; private Vector3 velocity; // Stores our falling speed private bool isGrounded; // Are we touching the floor? // Inputs private InputSystem_Actions inputActions; private Vector2 moveInput; void Awake() { inputActions = new InputSystem_Actions(); controller = GetComponent(); cameraTransform = Camera.main.transform; Cursor.lockState = CursorLockMode.Locked; Cursor.visible = false; // Bind Inputs inputActions.Player.Move.performed += ctx => moveInput = ctx.ReadValue(); inputActions.Player.Move.canceled += ctx => moveInput = Vector2.zero; inputActions.Player.Interact.started += ctx => TryInteract(); } void OnEnable() => inputActions.Enable(); void OnDisable() => inputActions.Disable(); void Update() { HandleGravity(); // <--- NEW GRAVITY FUNCTION HandleMovement(); HandleLook(); UpdateInteractionUI(); } void HandleGravity() { // If the trap disabled our controller, do not apply gravity! if (controller == null || !controller.enabled) return; // Check if the controller thinks it's on the ground isGrounded = controller.isGrounded; if (isGrounded && velocity.y < 0) { // Reset falling speed when on ground (keep slightly negative to stick to floor) velocity.y = -2f; } // Apply Gravity over time velocity.y += gravity * Time.deltaTime; // Apply the velocity to the controller controller.Move(velocity * Time.deltaTime); } void HandleMovement() { if (controller == null || !controller.enabled) return; Vector3 move = transform.right * moveInput.x + transform.forward * moveInput.y; controller.Move(move * moveSpeed * Time.deltaTime); } // ... (Keep HandleLook, UpdateInteractionUI, and TryInteract exactly the same as before) // For brevity, I am not pasting the repeated Look/Interact code here, // but ensure you keep those functions in your file! // If you need the full paste again, let me know. // ------------------------------------------------------------------------ // PASTE YOUR HandleLook, UpdateInteractionUI, and TryInteract HERE // ------------------------------------------------------------------------ void HandleLook() { Vector2 rawInput = inputActions.Player.Look.ReadValue(); float mouseX = rawInput.x * mouseSensitivity * Time.deltaTime; float mouseY = rawInput.y * mouseSensitivity * Time.deltaTime; verticalRotation -= mouseY; verticalRotation = Mathf.Clamp(verticalRotation, -maxLookAngle, maxLookAngle); cameraTransform.localRotation = Quaternion.Euler(verticalRotation, 0f, 0f); transform.Rotate(Vector3.up * mouseX); } void UpdateInteractionUI() { Ray ray = new Ray(cameraTransform.position, cameraTransform.forward); RaycastHit hit; if (Physics.Raycast(ray, out hit, interactionDistance, interactionLayer)) { IInteractable interactable = hit.collider.GetComponent(); if (interactable != null && InteractionUI.Instance != null) InteractionUI.Instance.UpdatePrompt(interactable.GetDescription()); else if (InteractionUI.Instance != null) InteractionUI.Instance.ClearPrompt(); } else if (InteractionUI.Instance != null) InteractionUI.Instance.ClearPrompt(); } void TryInteract() { Ray ray = new Ray(cameraTransform.position, cameraTransform.forward); RaycastHit hit; if (Physics.Raycast(ray, out hit, interactionDistance, interactionLayer)) { IInteractable interactable = hit.collider.GetComponent(); if (interactable != null) { interactable.Interact(); if (InteractionUI.Instance != null) InteractionUI.Instance.UpdatePrompt(interactable.GetDescription()); } } } }