92 lines
2.8 KiB
C#
92 lines
2.8 KiB
C#
using ActionRPG.Input;
|
|
using ActionRPG.Interfaces;
|
|
using UnityEngine;
|
|
using static ActionRPG.Interfaces.InteractionType;
|
|
|
|
namespace ActionRPG.Interaction
|
|
{
|
|
/// <summary>
|
|
/// Casts a ray from the player's camera each frame to detect IInteractable objects.
|
|
/// Subscribes to PlayerInputReader to trigger interaction on the correct input.
|
|
/// </summary>
|
|
[RequireComponent(typeof(PlayerInputReader))]
|
|
public class PlayerInteractor : MonoBehaviour
|
|
{
|
|
[Header("Raycast")]
|
|
[SerializeField] private Camera _camera;
|
|
[SerializeField, Min(0f)] private float _interactRange = 2.5f;
|
|
[SerializeField] private LayerMask _interactableLayer;
|
|
|
|
private PlayerInputReader _input;
|
|
private IInteractable _currentTarget;
|
|
|
|
private void Awake()
|
|
{
|
|
_input = GetComponent<PlayerInputReader>();
|
|
|
|
if (_camera == null)
|
|
_camera = Camera.main;
|
|
}
|
|
|
|
private void OnEnable()
|
|
{
|
|
_input.OnInteractStarted += HandleInteractPress;
|
|
_input.OnInteractPerformed += HandleInteractHold;
|
|
}
|
|
|
|
private void OnDisable()
|
|
{
|
|
_input.OnInteractStarted -= HandleInteractPress;
|
|
_input.OnInteractPerformed -= HandleInteractHold;
|
|
ClearTarget();
|
|
}
|
|
|
|
private void Update()
|
|
{
|
|
Ray ray = new Ray(_camera.transform.position, _camera.transform.forward);
|
|
|
|
if (Physics.Raycast(ray, out RaycastHit hit, _interactRange, _interactableLayer))
|
|
{
|
|
IInteractable target = hit.collider.GetComponentInParent<IInteractable>();
|
|
|
|
if (target != null && target != _currentTarget)
|
|
{
|
|
ClearTarget();
|
|
_currentTarget = target;
|
|
_currentTarget.OnFocused();
|
|
}
|
|
}
|
|
else
|
|
{
|
|
ClearTarget();
|
|
}
|
|
}
|
|
|
|
private void HandleInteractPress()
|
|
{
|
|
if (_currentTarget?.InteractionType == InteractionType.Press)
|
|
_currentTarget.Interact();
|
|
}
|
|
|
|
private void HandleInteractHold()
|
|
{
|
|
if (_currentTarget?.InteractionType == InteractionType.Hold)
|
|
_currentTarget.Interact();
|
|
}
|
|
|
|
private void ClearTarget()
|
|
{
|
|
if (_currentTarget == null) return;
|
|
_currentTarget.OnLostFocus();
|
|
_currentTarget = null;
|
|
}
|
|
|
|
private void OnDrawGizmosSelected()
|
|
{
|
|
if (_camera == null) return;
|
|
Gizmos.color = _currentTarget != null ? Color.green : Color.yellow;
|
|
Gizmos.DrawRay(_camera.transform.position, _camera.transform.forward * _interactRange);
|
|
}
|
|
}
|
|
}
|