AI决策算法 之 GOAP (三)

源码地址:http://pan.baidu.com/s/1dFwzmfB


这篇我们使用上篇文章写的GOAP框架来完成一个实例:


实例内容:

AI有10HP, 需要去站岗,站岗完成扣5HP

当HP<=5必须去补充HP,找到HP球补充HP,每个HP球补充5HP




根据GOAP框架逻辑推断出需要:AI数据提供者,站岗Action,补充HPAction,HP点脚本,站岗点脚本, AI属性脚本


主要脚本:


AI数据提供者

[csharp] view plain copy
  1. public class Worker : MonoBehaviour,IGoap{  
  2.   
  3.     private PropertyComponent property;    //属性脚本  
  4.     public float moveSpeed = 3;            //移动速度  
  5.   
  6.     void Start()  
  7.     {  
  8.         property = GetComponent<PropertyComponent>();  
  9.     }  
  10.   
  11.     public System.Collections.Generic.HashSet<System.Collections.Generic.KeyValuePair<stringobject>> GetState()  
  12.     {  
  13.         HashSet<KeyValuePair<stringobject>> state = new HashSet<KeyValuePair<stringobject>>();  
  14.         //当前状态HP是否足够  
  15.         state.Add(new KeyValuePair<stringobject>("EnoughHP", property.HP > 5));  
  16.         return state;  
  17.     }  
  18.   
  19.     public System.Collections.Generic.HashSet<System.Collections.Generic.KeyValuePair<stringobject>> CreateGoalState()  
  20.     {  
  21.         HashSet<KeyValuePair<stringobject>> goal = new HashSet<KeyValuePair<stringobject>>();  
  22.         //站岗完成目标  
  23.         goal.Add(new KeyValuePair<stringobject>("SentryComplete"true));  
  24.         return goal;  
  25.     }  
  26.   
  27.     public void PlanFailed(System.Collections.Generic.HashSet<System.Collections.Generic.KeyValuePair<stringobject>> failedGoal)  
  28.     {  
  29.           
  30.     }  
  31.   
  32.     public void PlanFound(System.Collections.Generic.HashSet<System.Collections.Generic.KeyValuePair<stringobject>> goal, System.Collections.Generic.Queue<Action> actions)  
  33.     {  
  34.           
  35.     }  
  36.   
  37.     public void ActionsFinished()  
  38.     {  
  39.         Debug.LogError("FinishedSentry");  
  40.     }  
  41.   
  42.     public void PlanAborted(Action aborterAction)  
  43.     {  
  44.           
  45.     }  
  46.   
  47.     public bool MoveAgent(Action tagetAction)  
  48.     {  
  49.         //移动  
  50.         float step = moveSpeed * Time.deltaTime;  
  51.         gameObject.transform.position = Vector3.MoveTowards(gameObject.transform.position, tagetAction.target.transform.position, step);  
  52.   
  53.         if (gameObject.transform.position.Equals(tagetAction.target.transform.position))  
  54.         {  
  55.             tagetAction.IsInRange = true;  
  56.             return true;  
  57.         }  
  58.         else  
  59.             return false;  
  60.     }  
  61. }  

站岗Action

[csharp] view plain copy
  1. public class SentryAction : Action {  
  2.   
  3.     private SentryComponent targetSentry;      //站岗目标脚本  
  4.     private float SentryTimer = 0;             //站岗计时  
  5.     public float SentryTime = 3;  
  6.     bool isDone = false;                       //是否完成  
  7.   
  8.     public SentryAction()  
  9.     {  
  10.         AddPrecondition("EnoughHP"true);  //前置条件:必须HP足够  
  11.         AddEffect("SentryComplete"true);  //完成效果:站岗完成  
  12.     }  
  13.   
  14.   
  15.     public override void Reset()  
  16.     {  
  17.         targetSentry = null;  
  18.         SentryTimer = 0;  
  19.         isDone = false;  
  20.     }  
  21.   
  22.     public override bool IsDone()  
  23.     {  
  24.         return isDone;  
  25.     }  
  26.   
  27.   
  28.     public override bool CheckProcedualPrecondition(GameObject agent)  
  29.     {  
  30.         //得到最近的站岗目标  
  31.         SentryComponent[] sentryComponents = GameObject.FindObjectsOfType<SentryComponent>();  
  32.   
  33.   
  34.         SentryComponent temp = null;  
  35.   
  36.         foreach(var v in sentryComponents)  
  37.         {  
  38.             if (temp == null)  
  39.             {  
  40.                 temp = v;  
  41.                 continue;  
  42.             }  
  43.   
  44.             if (Vector3.Distance(agent.transform.position, v.transform.position) < Vector3.Distance(agent.transform.position, temp.transform.position))  
  45.                 temp = v;  
  46.         }  
  47.   
  48.         targetSentry = temp;  
  49.         target = temp.gameObject;  
  50.   
  51.         return temp != null;  
  52.     }  
  53.   
  54.     public override bool Perform(GameObject agent)  
  55.     {  
  56.         //站岗执行  
  57.         SentryTimer += Time.deltaTime;  
  58.         if(SentryTimer > SentryTime)  
  59.         {  
  60.             //站岗完成消耗HP  
  61.             agent.GetComponent<PropertyComponent>().HP -= 5;  
  62.             isDone = true;  
  63.         }  
  64.         return true;  
  65.     }  
  66.   
  67.     public override bool RequiresInRange()  
  68.     {  
  69.         return true;  
  70.     }  
  71. }  

补充HPAction

[csharp] view plain copy
  1. public class GetHPAction : Action {  
  2.   
  3.     private HPPointComponent targetHPPoint;     //HP点目标脚本  
  4.     bool isDone = false;  
  5.   
  6.     void Start()  
  7.     {  
  8.         AddEffect("EnoughHP"true);   //完成效果:HP补充到足够  
  9.     }  
  10.   
  11.     public override void Reset()  
  12.     {  
  13.         targetHPPoint = null;  
  14.         isDone = false;  
  15.     }  
  16.   
  17.     public override bool IsDone()  
  18.     {  
  19.         return isDone;  
  20.     }  
  21.   
  22.     public override bool CheckProcedualPrecondition(GameObject agent)  
  23.     {  
  24.         HPPointComponent[] tempComponents = GameObject.FindObjectsOfType<HPPointComponent>();  
  25.   
  26.   
  27.         HPPointComponent temp = null;  
  28.   
  29.         foreach (var v in tempComponents)  
  30.         {  
  31.             if (temp == null)  
  32.             {  
  33.                 temp = v;  
  34.                 continue;  
  35.             }  
  36.   
  37.             if (Vector3.Distance(agent.transform.position, v.transform.position) < Vector3.Distance(agent.transform.position, temp.transform.position))  
  38.                 temp = v;  
  39.         }  
  40.   
  41.         targetHPPoint = temp;  
  42.         target = temp.gameObject;  
  43.   
  44.         return temp != null;  
  45.     }  
  46.   
  47.     public override bool Perform(GameObject agent)  
  48.     {  
  49.         DestroyImmediate(targetHPPoint.gameObject);  
  50.         isDone = true;  
  51.         agent.GetComponent<PropertyComponent>().HP += 5;  
  52.         return true;  
  53.     }  
  54.   
  55.     public override bool RequiresInRange()  
  56.     {  
  57.         return true;  
  58.     }  
  59.   
  60. }  
原文地址:https://www.cnblogs.com/nafio/p/9137021.html