当前位置:   article > 正文

AI决策算法 之 GOAP (三)_unity中决策ai---goap 孙广东

unity中决策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数据提供者

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

站岗Action

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

补充HPAction

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




声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/小舞很执着/article/detail/1012413
推荐阅读
相关标签
  

闽ICP备14008679号