Files
OTG_8/Assets/_Scripts/Player/PlayerInteraction.cs
T
2026-06-04 23:22:13 +03:00

106 lines
3.1 KiB
C#

using OTGIntegrated.UI;
using UnityEngine;
namespace OTGIntegrated.Player
{
public interface IInteractable
{
Transform InteractTransform { get; }
string GetPrompt();
bool CanInteract(GameObject interactor);
void Interact(GameObject interactor);
}
public sealed class PlayerInteraction : MonoBehaviour
{
[SerializeField] private float interactionRadius = 2.6f;
[SerializeField] private LayerMask interactionMask = ~0;
public InteractionPromptUI promptUI;
private readonly Collider[] hits = new Collider[24];
private PlayerController playerController;
private IInteractable currentInteractable;
private void Awake()
{
playerController = GetComponent<PlayerController>();
if (promptUI == null)
{
promptUI = FindObjectOfType<InteractionPromptUI>();
}
}
private void Update()
{
if (playerController != null && !playerController.InputEnabled)
{
SetCurrent(null);
return;
}
FindNearestInteractable();
if (currentInteractable != null && Input.GetKeyDown(KeyCode.E))
{
currentInteractable.Interact(gameObject);
}
}
private void FindNearestInteractable()
{
int count = Physics.OverlapSphereNonAlloc(transform.position, interactionRadius, hits, interactionMask, QueryTriggerInteraction.Collide);
IInteractable nearest = null;
float nearestDistance = float.MaxValue;
for (int i = 0; i < count; i++)
{
Collider hit = hits[i];
if (hit == null)
{
continue;
}
IInteractable interactable = hit.GetComponentInParent<IInteractable>();
if (interactable == null || !interactable.CanInteract(gameObject))
{
continue;
}
Transform interactTransform = interactable.InteractTransform != null ? interactable.InteractTransform : hit.transform;
float distance = (interactTransform.position - transform.position).sqrMagnitude;
if (distance < nearestDistance)
{
nearestDistance = distance;
nearest = interactable;
}
}
SetCurrent(nearest);
}
private void SetCurrent(IInteractable interactable)
{
currentInteractable = interactable;
if (promptUI == null)
{
return;
}
if (currentInteractable == null)
{
promptUI.Hide();
}
else
{
promptUI.Show(currentInteractable.GetPrompt());
}
}
private void OnDrawGizmosSelected()
{
Gizmos.color = new Color(1f, 0.75f, 0.2f, 0.25f);
Gizmos.DrawSphere(transform.position, interactionRadius);
}
}
}