NPC Brain & decisions update

This commit is contained in:
Pedro Gomes 2024-06-17 18:05:58 +01:00
parent 90d52d491e
commit 7613269fa5
3 changed files with 54 additions and 1 deletions

View File

@ -14,4 +14,6 @@ public abstract class NPCDecision : ScriptableObject
public abstract void Interrupt(NPCBrain npc);
public bool IsRunning() => executeRoutine != null;
public abstract bool IsPossibleToExecute(NPCBrain npc);
}

View File

@ -66,4 +66,8 @@ public class NPCPatrolDecision : NPCDecision
agent = npc.Agent;
}
public override bool IsPossibleToExecute(NPCBrain npc)
{
return !npc.IsDead() && !npc.IsCasting();
}
}

View File

@ -2,15 +2,30 @@ 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());
@ -18,7 +33,39 @@ public class NPCBrain : MonoBehaviour
IEnumerator Decide()
{
yield return null;
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(Execute(currentlyExecutingDecision));
}
}
IEnumerator Execute(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;
}
}