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(); if (promptUI == null) { promptUI = FindObjectOfType(); } } 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(); 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); } } }