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);
}
}
}
}