1. using UnityEngine;
  2. using System.Collections;
  3.  
  4. public class AttackState : FSMState
  5. {
  6. public AttackState()
  7. {
  8. stateID = FSMStateID.Attacking;
  9. }
  10.  
  11. public override void Reason(Transform player, Transform npc)
  12. {
  13. if (npc.GetComponent<AIController>().stateInfo.normalizedTime >= 1.0f && npc.GetComponent<AIController>().stateInfo.IsName("Attack"))
  14. npc.GetComponent<AIController>().SetTransition(Transition.AttackOver);
  15. }
  16.  
  17. public override void Act(Transform player, Transform npc)
  18. {
  19. }
  20. }
  1. using UnityEngine;
  2. using System.Collections;
  3.  
  4. public class DeadState : FSMState
  5. {
  6. public DeadState()
  7. {
  8. stateID = FSMStateID.Dead;
  9. }
  10.  
  11. public override void Reason(Transform player, Transform npc)
  12. {
  13.  
  14. }
  15.  
  16. public override void Act(Transform player, Transform npc)
  17. {
  18. Animation animComponent = npc.GetComponent<Animation>();
  19. //animComponent.CrossFade("death");
  20. }
  21. }
  1. using UnityEngine;
  2. using System.Collections;
  3.  
  4. public class MoveState : FSMState
  5. {
  6. float rotateTime;
  7. float curSpeed;
  8. public MoveState()
  9. {
  10. stateID = FSMStateID.Move;
  11.  
  12. curSpeed = 1.0f;
  13. rotateTime = 0f;
  14. }
  15.  
  16. public override void Reason(Transform player, Transform npc)
  17. {
  18. float distance = Vector3.Distance(player.position, npc.position);
  19. if (distance <= )
  20. {
  21. if (npc.GetComponent<AIController>().attackCd == 0f)
  22. {
  23. npc.GetComponent<AIController>().SetTransition(Transition.ReachPlayer);
  24. npc.GetComponent<AIController>().attackCd = 5.0f;
  25. }
  26. }
  27. }
  28.  
  29. public override void Act(Transform player, Transform npc)
  30. {
  31. rotateTime -= Time.deltaTime;
  32. if (rotateTime <= )
  33. {
  34. rotateTime = 3.0f;
  35. Vector3 toTargetV3 = (player.position - npc.position).normalized;
  36. float direction = Vector3.Dot(toTargetV3, npc.forward);
  37. Vector3 u = Vector3.Cross(toTargetV3, npc.forward);
  38. if (direction > ) { direction = 1f; }
  39. if (direction < -) { direction = -1f; }
  40. if (Mathf.Abs(direction) == 1f)
  41. return;
  42. direction = Mathf.Acos(direction) * Mathf.Rad2Deg;
  43. npc.rotation = npc.rotation * Quaternion.Euler(new Vector3(, direction * (u.y >= ? - : ), ));
  44. }
  45.  
  46. float distance = Vector3.Distance(player.position, npc.position);
  47. if (distance >= )
  48. {
  49. npc.GetComponent<AIController>().animator.SetFloat("Blend", 1f);
  50. curSpeed = 2f;
  51. }
  52. else if (distance < && distance >= )
  53. {
  54. npc.GetComponent<AIController>().animator.SetFloat("Blend", 0.5f);
  55. curSpeed = 1f;
  56. }
  57. else
  58. {
  59. npc.GetComponent<AIController>().animator.SetFloat("Blend", 0f);
  60. curSpeed = ;
  61. }
  62. npc.Translate(npc.transform.forward * Time.deltaTime * curSpeed, Space.World);
  63. }
  64. }
  1. using UnityEngine;
  2. using System.Collections;
  3. using System.Collections.Generic;
  4.  
  5. /// <summary>
  6. /// This class is adapted and modified from the FSM implementation class available on UnifyCommunity website
  7. /// The license for the code is Creative Commons Attribution Share Alike.
  8. /// It's originally the port of C++ FSM implementation mentioned in Chapter01 of Game Programming Gems 1
  9. /// You're free to use, modify and distribute the code in any projects including commercial ones.
  10. /// Please read the link to know more about CCA license @http://creativecommons.org/licenses/by-sa/3.0/
  11. /// </summary>
  12.  
  13. //定义枚举,为可能的转换分配编号
  14. public enum Transition
  15. {
  16. SawPlayer = , //看到玩家
  17. ReachPlayer, //接近玩家
  18. LostPlayer, //玩家离开视线
  19. NoHealth, //死亡
  20. AttackOver, //结束攻击
  21. }
  22.  
  23. /// <summary>
  24. /// 定义枚举,为可能的状态分配编号ID
  25. /// </summary>
  26. public enum FSMStateID
  27. {
  28. Move = ,
  29. Attacking, //攻击编号
  30. Patrolling , //巡逻编号
  31. Chasing, //追逐编号
  32. Dead, //死亡编号
  33. }
  34.  
  35. public class AdvancedFSM : FSM
  36. {
  37. //FSM中的所有状态组成的列表
  38. private List<FSMState> fsmStates;
  39. //当前状态的编号
  40. //The fsmStates are not changing directly but updated by using transitions
  41. private FSMStateID currentStateID;
  42. public FSMStateID CurrentStateID { get { return currentStateID; } }
  43. //当前状态
  44. private FSMState currentState;
  45. public FSMState CurrentState { get { return currentState; } }
  46.  
  47. public AdvancedFSM()
  48. {
  49. //新建一个空的状态列表
  50. fsmStates = new List<FSMState>();
  51. }
  52.  
  53. /// <summary>
  54. ///向状态列表中加入一个新的状态
  55. /// </summary>
  56. public void AddFSMState(FSMState fsmState)
  57. {
  58. //检查要加入的新状态是否为空,如果空就报错
  59. if (fsmState == null)
  60. {
  61. Debug.LogError("FSM ERROR: Null reference is not allowed");
  62. }
  63.  
  64. // First State inserted is also the Initial state
  65. // the state the machine is in when the simulation begins
  66. //如果插入的这个状态时,列表还是空的,那么将它加入列表并返回
  67. if (fsmStates.Count == )
  68. {
  69. fsmStates.Add(fsmState);
  70. currentState = fsmState;
  71. currentStateID = fsmState.ID;
  72. return;
  73. }
  74.  
  75. // 检查要加入的状态是否已经在列表里,如果是,报错返回
  76. foreach (FSMState state in fsmStates)
  77. {
  78. if (state.ID == fsmState.ID)
  79. {
  80. Debug.LogError("FSM ERROR: Trying to add a state that was already inside the list");
  81. return;
  82. }
  83. }
  84. //如果要加入的状态不在列表中,将它加入列表
  85. fsmStates.Add(fsmState);
  86. }
  87.  
  88. //从状态中删除一个状态
  89. public void DeleteState(FSMStateID fsmState)
  90. {
  91. // 搜索整个状态列表,如果要删除的状态在列表中,那么将它移除,否则报错
  92. foreach (FSMState state in fsmStates)
  93. {
  94. if (state.ID == fsmState)
  95. {
  96. fsmStates.Remove(state);
  97. return;
  98. }
  99. }
  100. Debug.LogError("FSM ERROR: The state passed was not on the list. Impossible to delete it");
  101. }
  102.  
  103. /// <summary>
  104. /// 根据当前状态,和参数中传递的转换,转换到新状态
  105. /// </summary>
  106. public void PerformTransition(Transition trans)
  107. {
  108. // 根绝当前的状态类,以Trans为参数调用它的GetOutputState方法
  109. //确定转换后的新状态
  110. FSMStateID id = currentState.GetOutputState(trans);
  111.  
  112. // 将当前状态编号设置为刚刚返回的新状态编号
  113. currentStateID = id;
  114.  
  115. //根绝状态编号查找状态列表,将当前状态设置为查找到的状态
  116. foreach (FSMState state in fsmStates)
  117. {
  118. if (state.ID == currentStateID)
  119. {
  120. currentState = state;
  121. break;
  122. }
  123. }
  124. }
  125. }
  1. using UnityEngine;
  2. using System.Collections;
  3.  
  4. public class FSM : MonoBehaviour
  5. {
  6. //玩家位置
  7. protected Transform playerTransform;
  8.  
  9. //下一个巡逻点
  10. protected Vector3 destPos;
  11.  
  12. //巡逻点表单
  13. protected GameObject[] pointList;
  14.  
  15. //子弹信息
  16. protected float shootRate;
  17. protected float elapsedTime;
  18.  
  19. protected virtual void Initialize() {}
  20. protected virtual void FSMUpdate() {}
  21. protected virtual void FSMFixedUpdate() {}
  22.  
  23. //初始化信息
  24. void Start()
  25. {
  26. Initialize();
  27. }
  28.  
  29. // 循环执行子类FSMUpdate方法
  30. void Update ()
  31. {
  32. FSMUpdate();
  33. }
  34.  
  35. void FixedUpdate()
  36. {
  37. FSMFixedUpdate();
  38. }
  39. }
  1. using UnityEngine;
  2. using System.Collections;
  3. using System.Collections.Generic;
  4.  
  5. /// <summary>
  6. /// This class is adapted and modified from the FSM implementation class available on UnifyCommunity website
  7. /// The license for the code is Creative Commons Attribution Share Alike.
  8. /// It's originally the port of C++ FSM implementation mentioned in Chapter01 of Game Programming Gems 1
  9. /// You're free to use, modify and distribute the code in any projects including commercial ones.
  10. /// Please read the link to know more about CCA license @http://creativecommons.org/licenses/by-sa/3.0/
  11.  
  12. /// This class represents the States in the Finite State System.
  13. /// Each state has a Dictionary with pairs (transition-state) showing
  14. /// which state the FSM should be if a transition is fired while this state
  15. /// is the current state.
  16. /// Reason method is used to determine which transition should be fired .
  17. /// Act method has the code to perform the actions the NPC is supposed to do if it磗 on this state.
  18. /// </summary>
  19. public abstract class FSMState
  20. {
  21. //字典,字典中每一项都记录了一个“转换-状态”对 的信息
  22. protected Dictionary<Transition, FSMStateID> map = new Dictionary<Transition, FSMStateID>();
  23. //状态编号ID
  24. protected FSMStateID stateID;
  25. public FSMStateID ID { get { return stateID; } }
  26.  
  27. /// <summary>
  28. /// 向字典添加项,每项是一个"转换--状态"对
  29. /// </summary>
  30. /// <param name="transition"></param>
  31. /// <param name="id"></param>
  32. public void AddTransition(Transition transition, FSMStateID id)
  33. {
  34. //检查这个转换(可以看做是字典的关键字)是否在字典里
  35. if (map.ContainsKey(transition))
  36. {
  37. //一个转换只能对应一个新状态
  38. Debug.LogWarning("FSMState ERROR: transition is already inside the map");
  39. return;
  40. }
  41. //如果不在字典,那么将这个转换和转换后的状态作为一个新的字典项,加入字典
  42. map.Add(transition, id);
  43. }
  44.  
  45. /// <summary>
  46. /// 从字典中删除项
  47. /// </summary>
  48. /// <param name="trans"></param>
  49. public void DeleteTransition(Transition trans)
  50. {
  51. // 检查是否在字典中,如果在,移除
  52. if (map.ContainsKey(trans))
  53. {
  54. map.Remove(trans);
  55. return;
  56. }
  57. //如果要删除的项不在字典中,报告错误
  58. Debug.LogError("FSMState ERROR: Transition passed was not on this State List");
  59. }
  60.  
  61. /// <summary>
  62. /// 通过查询字典,确定在当前状态下,发生trans转换时,应该转换到新的状态编号并返回
  63. /// </summary>
  64. /// <param name="trans"></param>
  65. /// <returns></returns>
  66. public FSMStateID GetOutputState(Transition trans)
  67. {
  68. return map[trans];
  69. }
  70.  
  71. /// <summary>
  72. /// 用来确定是否需要转换到其他状态,应该发生哪个转换
  73. /// </summary>
  74. /// <param name="player"></param>
  75. /// <param name="npc"></param>
  76. public abstract void Reason(Transform player, Transform npc);
  77.  
  78. /// <summary>
  79. /// 定义了在本状态的角色行为,移动,动画等
  80. /// </summary>
  81. /// <param name="player"></param>
  82. /// <param name="npc"></param>
  83. public abstract void Act(Transform player, Transform npc);
  84. }
  1. using UnityEngine;
  2. using System.Collections;
  3.  
  4. public class AIController : AdvancedFSM
  5. {
  6. private int health;
  7. public Animator animator;
  8. public AnimatorStateInfo stateInfo;
  9. public float attackCd;
  10. //Initialize the Finite state machine for the NPC tank
  11. protected override void Initialize()
  12. {
  13. health = ;
  14.  
  15. elapsedTime = 0.0f;
  16. shootRate = 0.5f;
  17. attackCd = 0f;
  18.  
  19. //Get the target enemy(Player)
  20. GameObject objPlayer = GameObject.FindGameObjectWithTag("Player");
  21. playerTransform = objPlayer.transform;
  22.  
  23. if (!playerTransform)
  24. print("Player doesn't exist.. Please add one with Tag named 'Player'");
  25. animator = this.GetComponentInChildren<Animator>();
  26. //Start Doing the Finite State Machine
  27. ConstructFSM();
  28. }
  29.  
  30. //Update each frame
  31. protected override void FSMUpdate()
  32. {
  33. //Check for health
  34. elapsedTime += Time.deltaTime;
  35. if (attackCd > )
  36. {
  37. attackCd -= Time.deltaTime;
  38. if (attackCd <= )
  39. attackCd = ;
  40. }
  41. }
  42.  
  43. protected override void FSMFixedUpdate()
  44. {
  45. stateInfo = animator.GetCurrentAnimatorStateInfo();
  46. CurrentState.Reason(playerTransform, transform);
  47. CurrentState.Act(playerTransform, transform);
  48. }
  49.  
  50. public void SetTransition(Transition t)
  51. {
  52. PerformTransition(t);
  53. animator.SetInteger("StateI", (int)CurrentStateID);
  54. }
  55.  
  56. private void ConstructFSM()
  57. {
  58. //Get the list of points
  59. pointList = GameObject.FindGameObjectsWithTag("PatrolPoint");
  60.  
  61. Transform[] waypoints = new Transform[pointList.Length];
  62. int i = ;
  63. foreach(GameObject obj in pointList)
  64. {
  65. waypoints = obj.transform;
  66. i++;
  67. }
  68.  
  69. MoveState move = new MoveState();
  70. move.AddTransition(Transition.ReachPlayer,FSMStateID.Attacking);
  71.  
  72. AttackState attack = new AttackState();
  73. attack.AddTransition(Transition.AttackOver,FSMStateID.Move);
  74.  
  75. AddFSMState(move);
  76. AddFSMState(attack);
  77. }
  78.  
  79. /// <summary>
  80. /// Check the collision with the bullet
  81. /// </summary>
  82. /// <param name="collision"></param>
  83. void OnCollisionEnter(Collision collision)
  84. {
  85. //Reduce health
  86. if (collision.gameObject.tag == "Bullet")
  87. {
  88. health -= ;
  89.  
  90. if (health <= )
  91. {
  92. Debug.Log("Switch to Dead State");
  93. SetTransition(Transition.NoHealth);
  94. }
  95. }
  96. }
  97.  
  98. // Shoot the bullet
  99. public void ShootBullet()
  100. {
  101. if (elapsedTime >= shootRate)
  102. {
  103. elapsedTime = 0.0f;
  104. }
  105. }
  106. }
  1. using UnityEngine;
  2. using System.Collections;
  3.  
  4. public class CameraFollow : MonoBehaviour
  5. {
  6. public Transform target;
  7. public Vector3 offest;
  8.  
  9. void LateUpdate()
  10. {
  11. transform.position = target.position + offest;
  12. }
  13. }

使用有限状态机(FSM)编写的敌人AI的更多相关文章

  1. Atitit. 有限状态机 fsm 状态模式

    Atitit. 有限状态机 fsm 状态模式 1. 有限状态机 1 2. "状态表"和"状态轮换表" 1 3. 有限状态机概念(状态(State)事件(Even ...

  2. 【转】利用Behavior Designer制作敌人AI

    http://www.unity.5helpyou.com/3112.html 本篇unity3d教程,我们来学习下利用Behavior Designer行为树插件来制作敌人AI,下面开始! Beha ...

  3. Unity3D 敌人AI 和 动画( Animator )系统的实例讲解

    在这个实例中,我们要做一些敌人AI的简单实现,其中自动跟随和动画是重点,我们要达到的目标如下: 1.敌人能够自动跟随主角 2.敌人模型一共有四个动作:Idle(空闲) Run(奔跑) Attack(攻 ...

  4. 有限状态机FSM(自动售报机Verilog实现)

    有限状态机FSM(自动售报机Verilog实现) FSM 状态机就是一种能够描述具有逻辑顺序和时序顺序事件的方法. 状态机有两大类:Mealy型和Moore型. Moore型状态机的输出只与当前状态有 ...

  5. cocos2d-x 游戏开发之有限状态机(FSM) (四)

    cocos2d-x 游戏开发之有限状态机(FSM) (四) 虽然我们了解了FSM,并且可以写自己的FSM,但是有更好的工具帮我们完成这个繁琐的工作.SMC(http://smc.sourceforge ...

  6. cocos2d-x 游戏开发之有限状态机(FSM) (三)

    cocos2d-x 游戏开发之有限状态机(FSM) (三) 有限状态机简称FSM,现在我们创建一个专门的FSM类,负责管理对象(Monkey)的状态.然后Monkey类就实现了行为与状态分离.Monk ...

  7. cocos2d-x 游戏开发之有限状态机(FSM) (一)

    cocos2d-x 游戏开发之有限状态机(FSM) (一) 参考:http://blog.csdn.net/mgphuang/article/details/5845252<Cocos2d-x游 ...

  8. cocos2d-x 游戏开发之有限状态机(FSM) (二)

    cocos2d-x 游戏开发之有限状态机(FSM)  (二) 1 状态模式

  9. 有限状态机FSM

    有限状态机(Finite-state machine)又称有限状态自动机,是表示有限个状态以及在这些状态之间的转移和动作等行为的数学模型.常用与:正则表达式引擎,编译器的词法和语法分析,游戏设计,网络 ...

随机推荐

  1. 关于c语言的一个小bug(c专家编程)

    不多说,说了都是累赘!直接看代码吧! #include <stdio.h> int array[] = {23, 34, 12, 17, 204, 99, 16}; #define TOT ...

  2. Spring 反转控制(IOC) 依赖注入(DI)

    简单的理解: 之前是我为了完成业务A 需要某个对象B的支持 那么我在这个业务A中就会创建一个对象B使用,说白了就是我根据需求来控制对象B, 而spring的ioc把对象B的控制权从业务A手中拿到自己手 ...

  3. 关于 linux ssh 的配置.

    一.禁止root用户远程登录: # cd /etc/ssh # vi sshd_config  将 permitRootLogin 后面的值改成 no 如下图: 然后再重启sshd服务即可,如下: # ...

  4. 《JavaScript 闯关记》之垃圾回收和内存管理

    JavaScript 具有自动垃圾收集机制(GC:Garbage Collecation),也就是说,执行环境会负责管理代码执行过程中使用的内存.而在 C 和 C++ 之类的语言中,开发人员的一项基本 ...

  5. EasyuiCombobox三级联动

    有许多刚接触Easyui中Combobox控件的朋友可能都会遇到的问题:如何将Combobox做成三级联动? 先本人有个三级联动的案例给大家参考参考,经测试能通过.注意Combobox绑定的数据是Js ...

  6. JS 根据Url参数名称来获取对应的值 方法封装

    function GetQueryString(name) { var reg = new RegExp("(^|&)" + name + "=([^&] ...

  7. Linux命令:FREE

    FREE(1)                       Linux User's Manual                      FREE(1) NAME free - Display a ...

  8. IOS Block 反向传值

    1.在需要像上一个界面传值的.h 文件实现代理方法 @property (nonatomic, copy) void(^isOpenHandler)(BOOL) ; 2.在执行操作的时候需要江操作的结 ...

  9. 在JS中得到表单中各项的值

    var form = document.getElementById("change");var pageNo = form.pageno.value;

  10. 使用LAMP创建基于wordpress的个从博客网站

    参考: http://blog.csdn.net/ck_boss/article/details/27866117 一.mysql配置 1.安装mysql yum install mysql-serv ...