编程文汇

游戏中的AI:行为树

#1

对于有限状态机来说,在拥有多种状态之后,状态之间的切换,切换条件的判断,都是很繁琐的,增加状态之后,还需要考虑是否要增加新的状态转换,以及是否要修改现有转换,整个开发过程比较繁琐。
相对而言,更轻量级,行为树更灵活,也更容易保持逻辑的正确性。值得深入学习。

以下视频应该是介绍行为树的最早出处了,一共有三段,视频的右侧有列表:
http://aigamedev.com/open/article/behavior-trees-part2/

基本概念:

  1. 叶子节点:就是执行具体行为
  2. 组合节点:包括Selector 和 Sequence。
    1. Selector : 就是多选一遍历子节点,遇到符合条件的就执行,返回,相当于过滤器链。
    2. Sequence:由多个连续行为构成的一个复杂行为:下图就是躲避敌人射击的例子:首先要跑向掩体,进入掩体,最后火力压制,以上三个行为才构成一个完整的躲避行为。如果,过程中的子任务失败,那么就相当于当前这个sequence无法进行下去,立即返回失败。
      sequence
  3. 装饰节点:一般用来指定准入条件,置于叶子节点和组合节点之前,就相当于程序中的if(xxx)判断,而组合节点和叶子节点,就是判断条件后面的语句块{}。行为树给装饰节点的定义基本如此,UE4里貌似也是这么用。
  4. 行为树是可以嵌套的:再怎么嵌套也是一棵树,所以,可以自由组合。

执行过程:

  1. 每次update,那么利用深度优先遍历树,再次对树进行评估,如果需要执行的还是上一次执行的节点,那么继续执行,否则就切换到新的running节点,必须在树上记录当前running节点。
  2. 树的遍历很可能是一个开销非常高的操作(比如查找视野内是否有人等类似操),如果每次update都遍历整个树,那么帧率很可能一下就降下来了。
  3. UE4的做法是,利用装饰节点,把转换条件的判断,放进装饰节点,这样,别的节点就只有操作。如果当前有running节点,那么继续执行running节点,这样的话是不是就不能及时切换状态、来了敌人不能及时攻击了??别急,除了继续执行running节点之外,UE还会以较低的频率遍历树,执行装饰节点,如果发现环境发生变化,需要转换状态,就可以立即转换状态。这种做法,兼顾了执行效率和响应及时性,不得不说,很聪明!!

参考资料:
个人觉得UE4的AI教程,真的很经典,透彻了解释了各种节点的职责,以及执行过程。如果,要想使用行为树,理解执行过程,必不可少。
https://en.wikipedia.org/wiki/Behavior_tree_(artificial_intelligence,_robotics_and_control)
https://www.youtube.com/watch?v=6VBCXvfNlCM
https://www.youtube.com/watch?v=2K6nX4A5n8w