归类到“3.5”中的这些文章都是基于3.5及之前旧版本的文档,其他目录(“文章”、“教程”、“手册”等)下的文档都用于3.6及以上新版本,如下图所示:

其中,3.6及以上新版本的主要特性如下所示:

behaviac在3.6之后的新版本,不再从运行时(程序端)导出类型信息,而是将类型信息的编辑工作全部放在了编辑器端,如下图所示:

workflow

新的设计是工作流从编辑器到运行时的单向箭头,也即类型信息完全在编辑器端设计,类型信息以源码的形式生成,程序端再把编辑器生成的类型信息相关的源码编译进程序。最后,程序端加载并执行编辑器导出的行为树。

整个设计有如下优点:

  • 流程简单,没有歧义
  • 程序员不需要写任何额外的代码,只需要把生成的代码加入工程
  • 支持方便的添加新的类型或属性、方法,修改已有的类型或属性、方法,不再需要多次修改
  • 属性不再必须是public的,被有效的封装
  • 数据的兼容性检测,尽力支持策划和程序员并行工作,尽力避免策划等待程序员更新
  • 支持热更新,将允许在代码不改变的情况下使用自定义变量以及修改行为树

工作区

工作区用于管理整个项目的配置,包括一些位置和语言等参数,如下图所示:

new_workspace

  • 工作区位置:保存工作区文件的目录,在该目录下会保存出*.workspace.xml的文件,该文件即是编辑器打开的工作区文件(或者称之为项目文件)。
  • 行为树源位置:对既有服务器,又有客户端的项目开发,可能需要共用行为树,这时候只要为服务器和客户端分别创建工作区,然后为它们设置相同的“行为树源位置”即可。这样,只需要编辑同一份行为树,就可以让服务器和客户端的AI逻辑保持一致。
  • 行为树导出位置:在该目录下,导出编辑好的行为树,并且需要在程序端设置的加载位置,以便程序运行起来后,加载所需的行为树。
  • 代码生成位置:用于存放后面将要描述的类型信息浏览器中编辑好的类型代码文件,还包含了一些“胶水”代码文件,都需要整合到运行时(游戏端)一起编译构建。
  • 程序端开发语言:可选cpp(即C++)和cs(即C#)两种,表示程序端的代码语言。结合上面所说的情况,可以支持服务器和客户端采用不同的语言编写代码,但共用同一份行为树数据。

类型信息

类型信息浏览器是进行类型信息查看和编辑的重要工具,可以管理(添加、删除、修改等)整个工作区所需的类型及其属性、方法、实例等信息,如下图所示:

meta_browser

点击类型信息浏览器下方的“应用”按钮,编辑出来的类型信息会保存在工作区文件所在的同目录下。例如,假设工作区文件是FirstWorkspace.workspace.xml,则在它所在的目录下,会自动保存出FirstWorkspace.meta.xml文件。

此外,点击“应用”按钮后,还会在工作区中设置的“代码生成位置”生成类型及其相关的“胶水”代码文件。点击左下方的“打开代码生成位置”按钮,弹出“behaviac_generated/types”目录,如下图所示:

export_path

注意:在自己的项目中,需要将“behaviac_generated/types/internal”目录中的所有cpp文件添加进自己的项目中,并且将“behaviac_types.h”头文件包含到自己的代码中以便能使用这些自动生成的“胶水”代码,如下图所示:

include_project

其中,“behaviac_generated/types/internal”目录中的behaviac_agent_member_visitor.h文件生成了用于访问类的私有属性和方法的“胶水”代码,behaviac_agent_meta.h/cpp文件生成了用于注册类及其属性、方法、实例等信息的“胶水”代码,这些“胶水”代码的作用是为了程序端运行时,可以通过名字自动取用到类及其成员属性、方法及其实例等。

FirstAgent.h/cpp是生成的Agent子类文件,在里面可以根据需要继续添加自己的代码,如下代码所示:

FirstAgent.h:

#ifndef _BEHAVIAC_FIRSTAGENT_H_
#define _BEHAVIAC_FIRSTAGENT_H_

#include "behaviac_agent_headers.h"

///<<< BEGIN WRITING YOUR CODE FILE_INIT

///<<< END WRITING YOUR CODE

class FirstAgent : public behaviac::Agent
    ///<<< BEGIN WRITING YOUR CODE FirstAgent
    ///<<< END WRITING YOUR CODE
{
public:
    FirstAgent();

    virtual ~FirstAgent();

    BEHAVIAC_DECLARE_AGENTTYPE(FirstAgent, behaviac::Agent)

private:
    int p1;
public:
    inline void _set_p1(int value)
    {
        p1 = value;
    }
    inline int& _get_p1()
    {
        return p1;
    }

public:
    void m1();

    ///<<< BEGIN WRITING YOUR CODE CLASS_PART

    ///<<< END WRITING YOUR CODE
};

///<<< BEGIN WRITING YOUR CODE FILE_UNINIT

///<<< END WRITING YOUR CODE

#endif

FirstAgent.cpp:

#include "FirstAgent.h"

///<<< BEGIN WRITING YOUR CODE FILE_INIT

///<<< END WRITING YOUR CODE

FirstAgent::FirstAgent()
{
    p1 = 0;

    ///<<< BEGIN WRITING YOUR CODE CONSTRUCTOR

    ///<<< END WRITING YOUR CODE
}

FirstAgent::~FirstAgent()
{
    ///<<< BEGIN WRITING YOUR CODE DESTRUCTOR

    ///<<< END WRITING YOUR CODE
}

void FirstAgent::m1()
{
    ///<<< BEGIN WRITING YOUR CODE m1

    ///<<< END WRITING YOUR CODE
}

///<<< BEGIN WRITING YOUR CODE FILE_UNINIT

///<<< END WRITING YOUR CODE

注意:自己的代码需要添加在“///<<< BEGIN WRITING YOUR CODE FILE_INIT”和“///<<< END WRITING YOUR CODE”之间,以便下次生成代码时,可以自动进行合并。

此外,如果该类并没有勾选“生成代码”选项,那么在点击“应用”按钮后,将不会生成该类的代码,需要你自己完全手工编写。为了提高手工编写代码的效率,可以点击类型信息浏览器右上方的“预览原型代码”按钮,将会弹出该类的原型代码,可以选择需要的内容复制到你的代码中,如下图所示:

preview_prototype

如果生成的文件中需要引用到你的项目中的其他头文件,可以点击上图中的“设置头文件”按钮,添加自己需要的.h文件,如下图所示:

set_headers

编辑行为树

根据在类型信息浏览器中创建的Agent子类,我们就可以开始创建和编辑行为树了。例如,行为树的根节点需要配置Agent类型,叶子节点需要配置相应的属性和方法,如下图所示:

right_bt

在编辑器中编辑的行为树称之为”源行为树“,但程序端只能加载并执行导出后的行为树。因此,编辑完行为树之后,需要统一导出。

导出行为树

打开“导出”窗口,如下图所示:

export

直接点击上图下方的 “导出”按钮,可以看到在工作区配置的“行为树导出位置”目录下,有了所有导出的行为树文件,如下图所示:

export_files

使用行为树

在程序端,需要指定上面提及的导出目录和文件格式,以便程序运行时能正常加载这些导出后的行为树,如下代码所示:

behaviac::Workspace::GetInstance()->SetFilePath("../tutorials/tutorial_0/cpp/exported");

behaviac::Workspace::GetInstance()->SetFileFormat(behaviac::Workspace::EFF_xml);

然后,调用相应的加载接口,就可以加载所需的行为树了,如下代码所示:

FirstAgent* g_FirstAgent = behaviac::Agent::Create<FirstAgent>();

g_FirstAgent->btload("FirstBT");

g_FirstAgent->btsetcurrent("FirstBT");

加载完行为树,Agent实例就可以执行设置的当前行为树了,如下代码所示:

g_FirstAgent->btexec();

此外,在“行为树导出位置”目录下的meta文件夹包含了*.meta.xml文件,该文件内含有Agent子类的自定义属性,可以用来做Agent子类新增(自定义)成员属性的热更新。

发表评论

电子邮件地址不会被公开。 必填项已用*标注