using System; using System.Collections; using System.Collections.Generic; using System.Linq; using Interaction; using JetBrains.Annotations; using UnityEngine; using UnityEngine.InputSystem; using UnityEngine.Serialization; using Utility; public class InteractionHandler : MonoBehaviour { [SerializeField] private Character _character; [FormerlySerializedAs("_pickupRadius")] [SerializeField, Tooltip("Der Radius in dem Gottfried Gegenstände aufheben kann."), Min(0.0f)] private float interactionRadius = 1.5f; /// /// Der Radius in dem Gottfried Gegenstände aufheben kann. /// public float InteractionRadius => interactionRadius; [FormerlySerializedAs("_pickupCollider")] [SerializeField] private CapsuleCollider _interactionCollider; [FormerlySerializedAs("_pickupablesInRange")] [SerializeField] private List _interactionsInRange = new(); public IReadOnlyList InteractionsInRange => _interactionsInRange; private int _selectedActionIndex = 0; public Interactible SelectedAction { get { FixSelection(); return _selectedActionIndex == -1 ? null : InteractionsInRange[_selectedActionIndex]; } } public void DoSelectPreviousAction(InputAction.CallbackContext context) { if (!context.performed) return; SelectPreviousAction(); } public void DoSelectNextAction(InputAction.CallbackContext context) { if (!context.performed) return; SelectNextAction(); } public void DoInteract(InputAction.CallbackContext context) { if (!context.performed) return; DoInteraction(); } private void DoInteraction() { if (InteractionsInRange.Count == 0) return; Interactible interactible = SelectedAction; if (interactible.IsBlocked()) { _character.SayItsImpossible(); return; } switch (interactible) { case PickupInteractible pickup: UnhighlightPickupable(interactible); _character.PickupItem(pickup); break; case UseInteractible usable: usable.OnUse?.Invoke(); break; case GiveItemInteractible giveItemAction: _character.GiveItemTo(giveItemAction.Developer); break; } } public void SelectPreviousAction() { _selectedActionIndex--; UpdateSelection(); } public void SelectNextAction() { _selectedActionIndex++; UpdateSelection(); } private void FixSelection() { if (_interactionsInRange.Count == 0) { _selectedActionIndex = -1; } else { if (_selectedActionIndex < 0) _selectedActionIndex = InteractionsInRange.Count - 1; else if (_selectedActionIndex >= InteractionsInRange.Count) _selectedActionIndex = 0; } } private void UpdateSelection() { FixSelection(); int index = 0; foreach (Interactible pickupable in _interactionsInRange) { pickupable.SetSelected(index == _selectedActionIndex); index++; } } private void OnTriggerEnter(Collider other) { Interactible interactible = other.gameObject.GetComponent(); if (interactible) { HighlightPickupable(interactible); } } void OnTriggerExit(Collider other) { Interactible interactible = other.gameObject.GetComponent(); if (interactible) { UnhighlightPickupable(interactible); } } private void HighlightPickupable(Interactible interactible) { if (!_interactionsInRange.Contains(interactible)) _interactionsInRange.Add(interactible); interactible.Highlight(true); UpdateSelection(); } private void UnhighlightPickupable(Interactible interactible) { interactible.Highlight(false); _interactionsInRange.Remove(interactible); UpdateSelection(); } // Wird aufgerufen, wenn ein Wert im Editor geändert wird void OnValidate() { if (_interactionCollider) { _interactionCollider.radius = interactionRadius; } } }