182 lines
4.5 KiB
C#
182 lines
4.5 KiB
C#
|
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;
|
||
|
|
||
|
/// <summary>
|
||
|
/// Der Radius in dem Gottfried Gegenstände aufheben kann.
|
||
|
/// </summary>
|
||
|
public float InteractionRadius => interactionRadius;
|
||
|
|
||
|
[FormerlySerializedAs("_pickupCollider")] [SerializeField]
|
||
|
private CapsuleCollider _interactionCollider;
|
||
|
|
||
|
[FormerlySerializedAs("_pickupablesInRange")] [SerializeField]
|
||
|
private List<Interactible> _interactionsInRange = new();
|
||
|
|
||
|
public IReadOnlyList<Interactible> 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<Interactible>();
|
||
|
|
||
|
if (interactible)
|
||
|
{
|
||
|
HighlightPickupable(interactible);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
void OnTriggerExit(Collider other)
|
||
|
{
|
||
|
Interactible interactible = other.gameObject.GetComponent<Interactible>();
|
||
|
|
||
|
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;
|
||
|
}
|
||
|
}
|
||
|
}
|