zoukankan      html  css  js  c++  java
  • 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. }  
  • 相关阅读:
    Luogu P4727 [HNOI2009]图的同构记数
    ARC 101 E
    JSOI2019 Round2 游记
    JSOI2019 Round1(十二省联考)游记
    Technocup 2019
    Codeforces Round #533 (Div. 2)比赛总结
    学习链接
    2018.12.29-2018.1.9安师大附中集训
    关于考试
    NOIP2018提高组 游记
  • 原文地址:https://www.cnblogs.com/nafio/p/9137021.html
Copyright © 2011-2022 走看看