using System.Collections; using UnityEngine; using UnityEngine.InputSystem; using Unheimlich.Core; using Unheimlich.Gameplay.Items; using Unheimlich.Gameplay.Player; using InputManager = Unheimlich.Managers.InputManager; namespace Unheimlich.Interactions.Core { /// /// Handles player item inspection mode. /// public class PlayerInspectionHandler : Singleton { [Header("Components")] [SerializeField] private Transform _inspectionHoldPoint; [Header("State")] public bool IsInspecting { get; private set; } = false; private InspectableItem _currentInspectedItem; private Coroutine _interactionListener; private bool _isUsingGamepad = false; public void ToggleInspection(InspectableItem item) { if (!IsInspecting) { StartInspection(item); } else { if (_interactionListener != null) StopInspection(); } } private void StartInspection(InspectableItem item) { IsInspecting = true; _currentInspectedItem = item; // Set Inspection context (handles cursor automatically) InputManager.SetContext(InputManager.InputContext.Inspection); // Disable OctoPlayer to prevent movement and look if (PlayerController.Instance?.Movement != null) { PlayerController.Instance.Movement.enabled = false; } item.PrepareForInspection(_inspectionHoldPoint); if (_interactionListener == null) _interactionListener = StartCoroutine(ListenForInteraction()); } private void StopInspection() { if (_interactionListener != null) { StopCoroutine(_interactionListener); _interactionListener = null; } StopInspectionInternal(); } private void StopInspectionInternal() { if (_currentInspectedItem != null) { _currentInspectedItem.Release(); _currentInspectedItem = null; StartCoroutine(DelayedToggleInput(true)); } IsInspecting = false; } private IEnumerator DelayedToggleInput(bool enable) { yield return new WaitForEndOfFrame(); // Re-enable OctoPlayer if (PlayerController.Instance?.Movement != null) { PlayerController.Instance.Movement.enabled = true; } // Restore Normal context (handles cursor automatically) InputManager.SetContext(InputManager.InputContext.Normal); yield break; } private IEnumerator ListenForInteraction() { yield return null; while (IsInspecting) { var interactAction = InputManager.GetInteractAction(); if (interactAction != null && interactAction.WasPressedThisFrame()) { StopInspectionInternal(); yield break; } yield return null; } _interactionListener = null; } private void Update() { if (IsInspecting && _currentInspectedItem != null) { HandleObjectRotation(); } } private void HandleObjectRotation() { if (_currentInspectedItem == null) return; Vector2 lookInput = Vector2.zero; bool hasInput = false; // Read input directly (not cached) if (Gamepad.current != null) { Vector2 stickInput = Gamepad.current.rightStick.ReadValue(); if (stickInput.sqrMagnitude > 0.01f) { lookInput = stickInput; hasInput = true; _isUsingGamepad = true; } } if (!hasInput && Mouse.current != null) { Vector2 mouseDelta = Mouse.current.delta.ReadValue(); if (mouseDelta.sqrMagnitude > 0.01f) { lookInput = mouseDelta; hasInput = true; _isUsingGamepad = false; } } // Only rotate if there's actual input if (hasInput) { // Normalize to get constant rotation speed regardless of input magnitude Vector2 direction = lookInput.normalized; float rotationMultiplier = _isUsingGamepad ? Time.deltaTime : 0.02f; float rotX = direction.y * _currentInspectedItem.RotationSpeed * rotationMultiplier; float rotY = direction.x * _currentInspectedItem.RotationSpeed * rotationMultiplier; _currentInspectedItem.transform.Rotate(transform.up, -rotY, Space.World); _currentInspectedItem.transform.Rotate(transform.right, rotX, Space.World); } } } }