using UnityEngine; using UnityEngine.InputSystem; public class FirstPersonController : MonoBehaviour { [Header("Movement Settings")] public float speed = 5.0f; public float mouseSensitivity = 10.0f; [Header("Camera Settings")] public Transform cameraTarget; public float minVerticalAngle = -90.0f; public float maxVerticalAngle = 90.0f; private CharacterController controller; private Vector2 moveInput; private Vector2 lookInput; private float verticalRotation = 0f; private Vector3 velocity = Vector3.zero; private float gravity = 9.81f; [Header("Input System")] public InputActionAsset inputActionAsset; private InputAction moveAction; private InputAction lookAction; private InputAction toggleMenuAction; // Single action for TAB [Header("Shop Menu")] [SerializeField] GameObject inventoryMenuUI; // Current inventory [SerializeField] GameObject buyMenuUI; // Buy inventory private bool isPaused = false; // Master state for Cursor + Camera void Start() { controller = GetComponent(); if (cameraTarget == null) Debug.LogError("Assign 'Camera Target'!"); // Initialize state: Locked cursor, Camera active SetPauseState(false); inventoryMenuUI.SetActive(false); buyMenuUI.SetActive(false); // Initialize shop menu UI } void OnEnable() { if (inputActionAsset != null) { // Find Actions moveAction = inputActionAsset.FindAction("Move"); lookAction = inputActionAsset.FindAction("Look"); // Make sure this name matches your Input Action Asset exactly! toggleMenuAction = inputActionAsset.FindAction("ToggleMenu"); // Enable Actions moveAction?.Enable(); lookAction?.Enable(); toggleMenuAction?.Enable(); // Subscribe to Events if (moveAction != null) { moveAction.performed += ctx => moveInput = ctx.ReadValue(); moveAction.canceled += ctx => moveInput = Vector2.zero; } if (lookAction != null) { lookAction.performed += ctx => lookInput = ctx.ReadValue(); lookAction.canceled += ctx => lookInput = Vector2.zero; } if (toggleMenuAction != null) { toggleMenuAction.performed += OnToggleMenuPerformed; } } } void OnDisable() { moveAction?.Disable(); lookAction?.Disable(); toggleMenuAction?.Disable(); } // Triggered when TAB is pressed void OnToggleMenuPerformed(InputAction.CallbackContext context) { // Toggle the boolean state isPaused = !isPaused; // Apply the new state SetPauseState(isPaused); } // Central function to handle what happens when paused/unpaused void SetPauseState(bool paused) { if (paused) { // FREEZE: Show cursor, unlock mouse, stop camera Cursor.lockState = CursorLockMode.None; Cursor.visible = true; inventoryMenuUI.SetActive(true); buyMenuUI.SetActive(true); } else { // RESUME: Hide cursor, lock mouse, allow camera Cursor.lockState = CursorLockMode.Locked; Cursor.visible = false; inventoryMenuUI.SetActive(false); buyMenuUI.SetActive(false); } } void Update() { // Always allow movement? Or restrict movement when paused? // If you want to stop walking when TAB is pressed, wrap this in "if (!isPaused)" HandleMovement(); // Only rotate camera if NOT paused if (!isPaused) { HandleRotation(); } } void HandleMovement() { Vector3 move = transform.right * moveInput.x + transform.forward * moveInput.y; velocity.y -= gravity * Time.deltaTime; move.y = velocity.y; controller.Move(move * speed * Time.deltaTime); } void HandleRotation() { // Horizontal (Body) float mouseX = lookInput.x * mouseSensitivity * Time.deltaTime; transform.Rotate(Vector3.up * mouseX); // Vertical (Camera Target) if (cameraTarget != null) { float mouseY = lookInput.y * mouseSensitivity * Time.deltaTime; verticalRotation -= mouseY; verticalRotation = Mathf.Clamp(verticalRotation, minVerticalAngle, maxVerticalAngle); cameraTarget.localRotation = Quaternion.Euler(verticalRotation, 0f, 0f); } } }