using System.Collections; using System.Collections.Generic; using UnityEngine; using UnityEngine.AI; using UnityEngine.Events; public class NPCBrain : MonoBehaviour { [Header("Decision Profile")] [SerializeField] private NPCDecisionProfile decisionProfile; NPCDecisionPriority currentlyExecutingDecision; bool isDead; BaseAbility currentlyQueuedAbility; bool isCasting; NavMeshAgent agent; public NavMeshAgent Agent => agent; public UnityEvent OnDecisionFinishedExecuting = new UnityEvent(); private void Awake() { isDead = false; isCasting = false; } private void Start() { StartCoroutine(Decide()); } IEnumerator Decide() { decisionProfile.decisions.Sort((decisionA, decisionB) => decisionB.priority.CompareTo(decisionA.priority)); foreach (NPCDecisionPriority decisionPriority in decisionProfile.decisions) { yield return null; if (currentlyExecutingDecision != null) if (currentlyExecutingDecision.priority >= decisionPriority.priority) continue; if (!decisionPriority.decision.IsPossibleToExecute(this)) continue; currentlyExecutingDecision = decisionPriority; StartCoroutine(TakeAction(currentlyExecutingDecision)); } } IEnumerator TakeAction(NPCDecisionPriority decisionPriority) { decisionPriority.decision.Execute(this); yield return new WaitUntil(() => decisionPriority.decision.IsRunning()); OnDecisionFinishedExecuting.Invoke(); } public bool IsCasting() { return currentlyQueuedAbility != null ? !currentlyQueuedAbility.castableWhileMoving : isCasting; } public bool IsDead() { return isDead; } } // idle // patrol // pursuit // recall // attack // block