Files
Gameshit/GOAP/Assets/Scrips/GOAP/AI_Agent.cs
2025-05-31 21:47:48 +02:00

135 lines
3.8 KiB
C#

using System.Collections.Generic;
using System.Linq;
using UnityEngine;
public class SubGoal
{
public Dictionary<string, int> goals;
public bool shouldRemove;
public SubGoal(string goalName, int value, bool shouldRemove)
{
goals = new Dictionary<string, int>
{
{ goalName, value }
};
this.shouldRemove = shouldRemove;
}
}
public class AI_Agent : MonoBehaviour
{
public List<AI_Action> actions = new List<AI_Action>();
public Dictionary<SubGoal, int> goals = new Dictionary<SubGoal, int>();
public AI_Inventory inventory = new AI_Inventory();
public AIStates agentWorldStates = new AIStates();
public float taskRange = 2.5f;
protected AI_Planner planner;
protected Queue<AI_Action> actionQueue;
protected AI_Action currentAction;
protected SubGoal currentGoal;
protected bool actionInvoked;
protected virtual void Start()
{
AI_Action[] actionsArray = GetComponents<AI_Action>();
foreach (AI_Action action in actionsArray)
{
actions.Add(action);
}
}
private void CompleteAction()
{
currentAction.isRunning = false;
currentAction.PostPerform();
actionInvoked = false;
}
private void OnDrawGizmosSelected()
{
Gizmos.color = Color.yellow;
Gizmos.DrawWireSphere(transform.position, taskRange);
}
private void LateUpdate()
{
if(currentAction != null && currentAction.isRunning)
{
float distanceToTarget = Vector3.Distance(currentAction.target.transform.position, transform.position);
if(currentAction.agent.hasPath && distanceToTarget < taskRange)
{
if(!actionInvoked)
{
Invoke(nameof(CompleteAction), currentAction.duration);
actionInvoked = true;
}
}
return;
}
if(planner == null || actionQueue == null)
{
planner = new AI_Planner();
var sortedGoals = from entry in goals orderby entry.Value descending select entry;
foreach(KeyValuePair<SubGoal, int> subGoal in sortedGoals)
{
actionQueue = planner.Plan(actions, subGoal.Key.goals, agentWorldStates);
if (actionQueue != null)
{
currentGoal = subGoal.Key;
break;
}
}
}
if(actionQueue != null && actionQueue.Count == 0)
{
if(currentGoal.shouldRemove)
{
goals.Remove(currentGoal);
}
planner = null;
}
if (actionQueue != null && actionQueue.Count > 0)
{
currentAction = actionQueue.Dequeue();
if (currentAction.PrePerform())
{
if (currentAction.target == null && !string.IsNullOrEmpty(currentAction.targetTag))
{
currentAction.target = GameObject.FindWithTag(currentAction.targetTag);
}
if (currentAction.target != null)
{
currentAction.isRunning = true;
// Check for AI_Area component
AI_Area area = currentAction.target.GetComponent<AI_Area>();
Vector3 destination;
if (area != null)
{
destination = area.GetRandomPointInArea();
}
else
{
destination = currentAction.target.transform.position;
}
currentAction.agent.SetDestination(destination);
}
}
else
{
actionQueue = null;
}
}
}
}