138 lines
4.7 KiB
C#
138 lines
4.7 KiB
C#
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<CharacterController>();
|
|
cameraTransform = Camera.main.transform;
|
|
|
|
Cursor.lockState = CursorLockMode.Locked;
|
|
Cursor.visible = false;
|
|
|
|
// Bind Inputs
|
|
inputActions.Player.Move.performed += ctx => moveInput = ctx.ReadValue<Vector2>();
|
|
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<Vector2>();
|
|
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<IInteractable>();
|
|
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<IInteractable>();
|
|
if (interactable != null)
|
|
{
|
|
interactable.Interact();
|
|
if (InteractionUI.Instance != null)
|
|
InteractionUI.Instance.UpdatePrompt(interactable.GetDescription());
|
|
}
|
|
}
|
|
}
|
|
} |