GameVsJam/3d Prototyp/Assets/InteractionHandler.cs

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;
}
}
}