87 lines
2.6 KiB
C#
87 lines
2.6 KiB
C#
using UnityEngine;
|
|
using Unheimlich.Managers;
|
|
|
|
namespace Unheimlich.Interactions.Core
|
|
{
|
|
/// <summary>
|
|
/// Detects interactable objects in front of the player camera using raycasts.
|
|
/// Triggers interaction when player presses interact button while looking at an interactable.
|
|
/// </summary>
|
|
public class InteractionHandler : MonoBehaviour
|
|
{
|
|
public static InteractionHandler Instance { get; private set; }
|
|
|
|
[Header("Settings")]
|
|
[SerializeField] private float _interactionRange = 1f;
|
|
[SerializeField] private LayerMask _interactableLayers;
|
|
[SerializeField] private float _raycastInterval = 0.1f;
|
|
|
|
private InteractableBase _currentInteractable;
|
|
private Camera _playerCamera;
|
|
private float _raycastTimer;
|
|
|
|
private static readonly Vector3 ViewportCenter = new Vector3(0.5f, 0.5f, 0f);
|
|
|
|
private void Awake()
|
|
{
|
|
if (Instance != null && Instance != this)
|
|
{
|
|
Destroy(this);
|
|
return;
|
|
}
|
|
Instance = this;
|
|
_playerCamera = GetComponent<Camera>();
|
|
}
|
|
|
|
private void Update()
|
|
{
|
|
_raycastTimer += Time.deltaTime;
|
|
|
|
if (_raycastTimer >= _raycastInterval)
|
|
{
|
|
CheckForInteractable();
|
|
_raycastTimer = 0f;
|
|
}
|
|
|
|
HandleInteractionInput();
|
|
}
|
|
|
|
/// <summary>
|
|
/// Performs raycast from camera center to detect interactable objects within range.
|
|
/// Updates the current interactable reference for input handling.
|
|
/// </summary>
|
|
private void CheckForInteractable()
|
|
{
|
|
Ray ray = _playerCamera.ViewportPointToRay(ViewportCenter);
|
|
|
|
if (Physics.Raycast(ray, out RaycastHit hit, _interactionRange, _interactableLayers))
|
|
{
|
|
InteractableBase hitInteractable = hit.collider.GetComponent<InteractableBase>();
|
|
_currentInteractable = hitInteractable;
|
|
}
|
|
else
|
|
_currentInteractable = null;
|
|
}
|
|
|
|
private void HandleInteractionInput()
|
|
{
|
|
if (PlayerInputManager.Instance != null &&
|
|
PlayerInputManager.Instance.InteractAction.action.WasPressedThisFrame())
|
|
{
|
|
if (_currentInteractable != null)
|
|
_currentInteractable.Interact(transform.parent.gameObject);
|
|
}
|
|
}
|
|
|
|
private void OnDrawGizmosSelected()
|
|
{
|
|
if (_playerCamera != null)
|
|
{
|
|
Gizmos.color = _currentInteractable != null ? Color.green : Color.red;
|
|
|
|
Ray ray = _playerCamera.ViewportPointToRay(ViewportCenter);
|
|
Gizmos.DrawRay(ray.origin, ray.direction * _interactionRange);
|
|
}
|
|
}
|
|
}
|
|
} |