本文档描述的是3.6及以后版本,对于3.5及以前的老版本请参考分类“3.5”。
对于行为树的调试,behaviac提供了连调和离线调试两大功能。
连调功能是在游戏运行的时候,编辑器可以连上游戏,实时的查看树的运行情况、变量的当前值并可以设置断点等;而离线调试实际上是回放运行时所产生的log。
本教程主要介绍连调的过程和相关的功能说明,离线调试可以参考文章《调试功能的说明》。
连调需要游戏是开发版本(即宏BEHAVIAC_RELEASE没有被定义),发布版本下没有连调的功能,可以参考文章《版本说明》和《开发功能开关》。
打开目录tutorials/tutorial_7/workspace中的工作区,并打开类型信息浏览器,可以看到类FirstAgent有一个成员属性p1和两个成员方法Start和Wait,如下图所示:
点击上图右下方的应用按钮,在生成的FirstAgent.cpp文件中,填写Start和Wait的方法内容如下代码所示:
void FirstAgent::Start() { ///<<< BEGIN WRITING YOUR CODE Start count = 0; ///<<< END WRITING YOUR CODE } behaviac::EBTStatus FirstAgent::Wait() { ///<<< BEGIN WRITING YOUR CODE Wait count++; printf("p1 = %i\n", p1); if (count == 10000) { return behaviac::BT_SUCCESS; } return behaviac::BT_RUNNING; ///<<< END WRITING YOUR CODE }
打开行为树demo,可以看到该行为树如下图所示:
为了在程序启动时,等待编辑器连接上才往后继续执行,需要在tutorial_7.cpp文件中的InitBehaviac方法中,添加如下代码:
behaviac::Config::SetSocketBlocking(true);
如果需要修改端口号,需要添加如下代码:
behaviac::Config::SetSocketPort(60636);
为了在连调时,程序端能够发送消息到编辑器端,需要在游戏循环中执行Workspace::DebugUpdate()方法,如下代码所示:
void UpdateLoop() { LOGI("UpdateLoop\n"); int frames = 0; behaviac::EBTStatus status = behaviac::BT_RUNNING; while (status == behaviac::BT_RUNNING) { LOGI("frame %d\n", ++frames); behaviac::Workspace::GetInstance()->DebugUpdate(); status = g_FirstAgent->btexec(); } }
另外,如果程序端是通过Workspace::Update()的方式来统一执行所有Agent实例的行为树,则不需要再额外调用Workspace::DebugUpdate()方法,详见文章《运行时端的执行流程》。
启动程序,可以看到如下图所示:
上面表示,程序端已经在开始等待编辑器的连接了。
点击编辑器工具栏中的“连接”按钮,如下图所示:
在弹出的“连接游戏”窗口中,设置相应的IP和端口号后,点击“确认”按钮开始连接游戏,如下图所示:
编辑器成功连接后,在左侧的实例节点列表中,会列出当前的Agent实例,如下图所示:
在“输出”窗口中,可以看到程序端发送过来的所有消息,编辑器也正是根据这些消息来相应的刷新当前的高亮执行路径和处理断点、刷新成员属性的当前值等,如下图所示:
鼠标双击实例节点列表中的节点FirstAgent_0_0,开始跟踪该实例的当前行为树的执行情况,可以看到行为树有了高亮的执行路径效果,表示当前返回Running的所有节点序列,如下图所示:
双击某个节点的左侧可以为该节点添加“进入”断点,双击某个节点的右侧可以为该节点添加“退出”断点,如下图所示:
上图中高亮的断点,表示当前行为树的执行已经停在该处。点击Timeline工具栏中的“继续”按钮或直接按F5快捷键,可以继续执行行为树,如下图所示:
在属性窗口中,可以查看当前实例的所有成员属性及其当前值,如下图所示:
为了方便调试,可以在上图中手工修改属性的值,该值会被发送到程序端,影响行为树的执行。
有关连调的使用还可以参考连调相关常见问题。
本教程相关的工作区和代码工程详见源码包的目录tutorials/tutorial_7。