java 行为树_游戏AI—行为树研究及实现

从上古卷轴中形形色色的人物,到NBA2K中挥洒汗水的球员,从使命召唤中诡计多端的敌人,到刺客信条中栩栩如生的人群。游戏AI几乎存在于游戏中的每个角落,默默构建出一个令人神往的庞大游戏世界。

那么这些复杂的AI又是怎么实现的呢?下面就让我们来了解并亲手实现一下游戏AI基础架构之一的行为树。

行为树简介

行为树是一种树状的数据结构,树上的每一个节点都是一个行为。每次调用会从根节点开始遍历,通过检查行为的执行状态来执行不同的节点。他的优点是耦合度低扩展性强,每个行为可以与其他行为完全独立。目前的行为树已经可以将几乎任意架构(如规划器,效用论等)应用于AI之上。

class BehaviorTree

{

public:

BehaviorTree(Behavior* InRoot) { Root = InRoot; }

void Tick()

{

Root->Tick();

}

bool HaveRoot() { return Root?true:false; }

void SetRoot(Behavior* InNode) { Root= InNode; }

void Release() { Root->Release(); }

private:

Behavior* Root;

};

上面提供了行为树的实现,行为树有一个根节点和一个Tick()方法,在游戏过程中每个一段时间会调用依次Tick方法,令行为树从根节点开始执行。

行为(behavior)

行为(behavior)是行为树最基础的概念,是几乎所有行为树节点的基类,是一个抽象接口,而如动作条件等节点则是它的具体实现。

下面是Behavior的实现,省略掉了一些简单的判断状态的方法完整源码可以参照文尾的github链接

class Behavior

{

public:

//释放对象所占资源

virtual void Release() = 0;

//包装函数,防止打破调用契约

EStatus Tick();

EStatus GetStatus() { return Status; }

virtual void AddChild(Behavior* Child){};

protected:

//创建对象请调用Create()释放对象请调用Release()

Behavior():Status(EStatus::Invalid){}

virtual ~Behavior() {}

virtual void OnInitialize() {};

virtual EStatus Update() = 0;

virtual void OnTerminate(EStatus Status) {};

protected:

EStatus Status;

};

Behavior接口是所有行为树节点的核心,且我规定所有节点的构造和析构方法都必须是protected,以防止在栈上创建对象,所有的节点对象通过Create()静态方法在堆上创建,通过Release()方法销毁,由于Behavior是个抽象接口,故没有提供Create()方法,本接口满足如下契约

在Update方法被首次调用前,调用一次OnInitialize函数,负责初始化等操作

Update()方法在行为树每次更新时调用且仅调用一次。

当行为不再处于运行状态时,调用一次OnTerminate(),并根据返回状态不同执行不同的逻辑

为了保证契约不被打破,我们将这三个方法包装在Tick()方法里。Tick()的实现如下

//update方法被首次调用前执行OnInitlize方法,每次行为树更新时调用一次update方法

//当刚刚更新的行为不再运行时调用OnTerminate方法

if (Status != EStatus::Running)

{

OnInitialize();

}

Status = Update();

if (Status != EStatus::Running)

{

OnTerminate(Status);

}

return Status;

其中返回值Estatus是一个枚举值,表示节点运行状态。

enum class EStatus:uint8_t

{

Invalid, //初始状态

Success, //成功

Failure, //失败

Running, //运行

Aborted, //终止

};

动作(Action)

动作是行为树的叶子节点,表示角色做的具体操作(如攻击,上弹,防御等),负责改变游戏世界的状态。动作节点可直接继承自Behavior节点,通过实现不同的Update()方法实现不同的逻辑,在OnInitialize()方法中获取数据和资源,在OnTerminate中释放资源。

//动作基类

class Action :public Behavior

{

public:

virtual void Releas

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值