P小二 P小二
← 返回文章 游戏AI 约 6 分钟

07.游戏AI方法之行为树

GameAI: 07.游戏AI方法之行为树

行为树(Behavior Tree) 是和分层状态机类似的知识系统,主要是用来描述在有限的任务集合中的各种转换。目前,行为树是创建AI角色的主导性工具。

行为树

行为树算是多种技术的一个综合,包括了分层状态机,调度,路径规划和动作执行等。 行为树和分层状态机相比,它模块化,易于理解,对于非开发人员也是非常友好,它们的主要区别是行为树主要是行为构成,而非状态。

行为树是一种树状结构,节点有三种类型: 序列节点,选择节点和装饰节点。

** **

序列节点

序列节点

按顺序执行多个子节点,如果遇到一个子节点不能执行,那就不继续执行。

按顺序执行多个子节点,如果遇到一个子节点不能执行,那就不继续执行。

例子: 先判断敌人是否可见,可见才走开。

选择节点

** **

**

选择节点

**

按顺序执行多个子节点,如果遇到一个子节点执行成功,那就不继续执行。

按顺序执行多个子节点,如果遇到一个子节点执行成功,那就不继续执行。

例子: 如果执行攻击成功,那不执行嘲讽和凝视。

** **

装饰节点

装饰节点,类似于装饰器模式,是用来以某种方式修改其他节点行为的。比如:结果取反/并/或,重复执行,获取执行时间等辅助功能。

所以,行为树基础节点只有序列节点和选择节点。

复合节点

复合节点,顾名思义就是把上面的两个节点结合起来。

比如,下面就是两个序列节点和一个选择节点组合。

比如,下面就是两个序列节点和一个选择节点组合。

吃豆人的行为树

吃豆人的行为树

上面是吃豆人的一个简单行为树。

处于寻找豆子的吃豆人,会按照顺序进行移动,找到豆子和吃下豆子等行为。 直到发现鬼魂为止。

在移动的时候,吃豆人会选择一个没有鬼魂的通道进行移动。

行为树实现

创建一个Task的基类:

using UnityEngine;using System.Collections;using System.Collections.Generic;public class Task : MonoBehaviour { public List children; protected bool result = false; protected bool isDone = false;}public virtual void SetResult(bool r) { result = r; isDone = true;}public virtual IEnumerator Run(){ SetResult(true); yield break;}public virtual IEnumerator RuntTask(){ yield result StartCorutine(Run());}


创建一个ConditionBT类:

- -
- -
- -
- -
- -
- -
- -
- -
- - ```
using UnityEngine;using System.Collections;public class ConditionBT: Task{    public override IEnumerator Run()    {        isDone = false;        bool r = false;        //todo        //编写你的行为逻辑        SetResult(r);        yield break;    }}

然后再来一个ActionBT类:

using UnityEngine;using System.Collections;public class ActionBT: Task{ public override IEnumerator Run() { isDone = false; //todo //编写你的行为逻辑 return base.Run();    }}


最后分别实现Sequence和Selector类。

- -
- -
- -
- -
- -
- -
- -
- -
- -
- -
- - ```
using UnityEngine;using System.Collections;public class Sequence: Task{    public override void SetResult(bool r)     {        if (r == true)            isDone = true;            }    public override IEnumerator RuntTask()    {        foreach (Task task in children)        {            yield return StartCorutine(task.RuntTask());                    }    }}

using UnityEngine;using System.Collections;public class Selector: Task{ public override void SetResult(bool r) { if (r == true) isDone = true; } public override IEnumerator RuntTask() { foreach (Task task in children) { yield return StartCorutine(task.RuntTask()); }}


**往期回顾:**

[06.游戏AI方法之分层状态机](http://mp.weixin.qq.com/s?__biz=MzAwNzc4MDgwNQ==&mid=2653126078&idx=1&sn=0e07de0e678bc2cb673bef7ee549ae83&chksm=80af3d14b7d8b4029077c74d68e4cf7049bc5994069a4d0b803139bc42961ae2e8e9bc2b8d00&scene=21#wechat_redirect)

[05.游戏AI方法之有限状态机](http://mp.weixin.qq.com/s?__biz=MzAwNzc4MDgwNQ==&mid=2653126044&idx=1&sn=2558f0d2b58d4d645cb741a2931637ca&chksm=80af3d36b7d8b420816b359499ad8de33070ad0f975e65bdd2bc4429e84611ab9de7ef112618&scene=21#wechat_redirect)

[04.《吃豆人》的游戏AI分析](http://mp.weixin.qq.com/s?__biz=MzAwNzc4MDgwNQ==&mid=2653126021&idx=1&sn=9217462543701f128854d306e3ebab5b&chksm=80af3d2fb7d8b4392c323ec87c204c753911be328f6eafa5ed24da37f006029b191e293753f8&scene=21#wechat_redirect)