using System.Collections.Generic; using UnityEngine; using System.Linq; using System.Threading.Tasks; using Input; namespace Interactions { /// /// Base class for all interaction action components /// These components respond to interaction events and can control the interaction flow /// public abstract class InteractionActionBase : MonoBehaviour { [Tooltip("Which interaction events this action should respond to")] public List respondToEvents = new List(); [Tooltip("Whether the interaction flow should wait for this action to complete")] public bool pauseInteractionFlow = true; protected InteractableBase parentInteractable; protected virtual void Awake() { // Get the parent interactable component parentInteractable = GetComponentInParent(); if (parentInteractable == null) { Debug.LogError($"[{GetType().Name}] Cannot find parent Interactable component!"); enabled = false; return; } } protected virtual void OnEnable() { if (parentInteractable != null) { parentInteractable.RegisterAction(this); } } protected virtual void OnDisable() { if (parentInteractable != null) { parentInteractable.UnregisterAction(this); } } /// /// Called when an interaction event occurs that this action is registered for /// /// The type of event that occurred /// A task that completes when the action is finished, or null if action won't execute public Task OnInteractionEvent(InteractionEventType eventType, PlayerTouchController player, FollowerController follower) { if (respondToEvents.Contains(eventType) && ShouldExecute(eventType, player, follower)) { if (pauseInteractionFlow) { return ExecuteAsync(eventType, player, follower); } else { // If we don't need to pause the flow, execute in the background // and return a completed task _ = ExecuteAsync(eventType, player, follower); return Task.FromResult(false); } } return null; } /// /// Execute the action for the given event asynchronously /// protected abstract Task ExecuteAsync(InteractionEventType eventType, PlayerTouchController player, FollowerController follower); /// /// Called to determine if this action should execute for the given event /// Override this to add additional conditions for execution /// protected virtual bool ShouldExecute(InteractionEventType eventType, PlayerTouchController player, FollowerController follower) { return true; } } }