145 lines
3.9 KiB
C#
145 lines
3.9 KiB
C#
using System.Collections;
|
|
using System.Collections.Generic;
|
|
using TMPro;
|
|
using UnityEngine;
|
|
using UnityEngine.UI;
|
|
|
|
public class GamepadInteractionController : MonoBehaviour
|
|
{
|
|
[Header("Settings")]
|
|
[SerializeField] private float interactionRadius = 3f;
|
|
[SerializeField] private float highlightRadius = 5f;
|
|
[SerializeField] private LayerMask interactableMask;
|
|
|
|
[Header("UI References")]
|
|
[SerializeField] private GameObject interactionPrompt;
|
|
[SerializeField] private Image interactionIcon;
|
|
[SerializeField] private TMP_Text interactionText;
|
|
|
|
private List<Interactable> nearbyInteractables = new List<Interactable>();
|
|
private Interactable currentTarget;
|
|
private bool isShowingInteractables;
|
|
PlayerController playerController;
|
|
|
|
private void Awake()
|
|
{
|
|
playerController = GetComponent<PlayerController>();
|
|
}
|
|
|
|
float rightTrigger;
|
|
private void Update()
|
|
{
|
|
// Show interactables when holding Right Trigger
|
|
rightTrigger = Input.GetAxisRaw("RightTrigger");
|
|
isShowingInteractables = rightTrigger > 0.5f;
|
|
|
|
if (isShowingInteractables)
|
|
{
|
|
UpdateNearbyInteractables();
|
|
HighlightClosestInteractable();
|
|
}
|
|
else
|
|
{
|
|
ClearHighlights();
|
|
}
|
|
|
|
// Interact with Right Bumper
|
|
if (Input.GetButtonDown("RightBumper") && currentTarget != null)
|
|
{
|
|
InteractWithCurrent();
|
|
}
|
|
}
|
|
Collider[] colliders;
|
|
private void UpdateNearbyInteractables()
|
|
{
|
|
nearbyInteractables.Clear();
|
|
colliders = Physics.OverlapSphere(transform.position, highlightRadius, interactableMask);
|
|
|
|
foreach (var collider in colliders)
|
|
{
|
|
if (collider.TryGetComponent<Interactable>(out var interactable))
|
|
{
|
|
nearbyInteractables.Add(interactable);
|
|
}
|
|
}
|
|
}
|
|
|
|
float closestDistance;
|
|
Interactable closest;
|
|
float distance;
|
|
private void HighlightClosestInteractable()
|
|
{
|
|
closestDistance = float.MaxValue;
|
|
closest = null;
|
|
|
|
foreach (var interactable in nearbyInteractables)
|
|
{
|
|
distance = Vector3.Distance(transform.position, interactable.transform.position);
|
|
if (distance < closestDistance)
|
|
{
|
|
closestDistance = distance;
|
|
closest = interactable;
|
|
}
|
|
}
|
|
|
|
// Only highlight if within interaction range
|
|
if (closest != null && closestDistance <= interactionRadius)
|
|
{
|
|
SetCurrentTarget(closest);
|
|
}
|
|
else
|
|
{
|
|
ClearCurrentTarget();
|
|
}
|
|
}
|
|
|
|
private void SetCurrentTarget(Interactable target)
|
|
{
|
|
if (currentTarget != target)
|
|
{
|
|
ClearCurrentTarget();
|
|
currentTarget = target;
|
|
|
|
// Show interaction prompt
|
|
interactionPrompt.SetActive(true);
|
|
interactionText.text = $"Press RB to {target.GetInteractionText()}";
|
|
|
|
// Highlight the interactable
|
|
target.OnFocused(this.transform, playerController, true);
|
|
target.OnHighlight();
|
|
}
|
|
}
|
|
|
|
private void ClearCurrentTarget()
|
|
{
|
|
if (currentTarget != null)
|
|
{
|
|
currentTarget.OnUnhighlight();
|
|
currentTarget = null;
|
|
interactionPrompt.SetActive(false);
|
|
}
|
|
}
|
|
|
|
private void ClearHighlights()
|
|
{
|
|
foreach (var interactable in nearbyInteractables)
|
|
{
|
|
interactable.OnUnhighlight();
|
|
}
|
|
nearbyInteractables.Clear();
|
|
ClearCurrentTarget();
|
|
}
|
|
|
|
private void InteractWithCurrent()
|
|
{
|
|
if (currentTarget != null)
|
|
{
|
|
distance = Vector3.Distance(transform.position, currentTarget.transform.position);
|
|
if (distance <= interactionRadius)
|
|
{
|
|
currentTarget.Interact(true);
|
|
}
|
|
}
|
|
}
|
|
}
|