173 lines
4.8 KiB
C#
173 lines
4.8 KiB
C#
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
|
|
{
|
|
/// <summary>
|
|
/// Handles player item inspection mode.
|
|
/// </summary>
|
|
public class PlayerInspectionHandler : Singleton<PlayerInspectionHandler>
|
|
{
|
|
|
|
[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);
|
|
}
|
|
}
|
|
}
|
|
} |