news 2026/7/14 6:05:01

教程7:行为树的连调-–-behaviac

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
教程7:行为树的连调-–-behaviac

原文

本文档描述的是3.6及以后版本,对于3.5及以前的老版本请参考分类“3.5”。

对于行为树的调试,behaviac提供了连调和离线调试两大功能。

连调功能是在游戏运行的时候,编辑器可以连上游戏,实时的查看树的运行情况、变量的当前值并可以设置断点等;而离线调试实际上是回放运行时所产生的log。

本教程主要介绍连调的过程和相关的功能说明,离线调试可以参考文章《调试功能的说明》。

连调需要游戏是开发版本(即宏BEHAVIAC_RELEASE没有被定义),发布版本下没有连调的功能,可以参考文章《版本说明》和《开发功能开关》。

打开目录tutorials/tutorial_7/workspace中的工作区,并打开类型信息浏览器,可以看到类FirstAgent有一个成员属性p1和两个成员方法Start和Wait,如下图所示:

点击上图右下方的应用按钮,在生成的FirstAgent.cpp文件中,填写Start和Wait的方法内容如下代码所示:

voidFirstAgent::Start(){///<<< BEGIN WRITING YOUR CODE Startcount=0;///<<< END WRITING YOUR CODE}behaviac::EBTStatusFirstAgent::Wait(){///<<< BEGIN WRITING YOUR CODE Waitcount++;printf("p1 = %i\n",p1);if(count==10000){returnbehaviac::BT_SUCCESS;}returnbehaviac::BT_RUNNING;///<<< END WRITING YOUR CODE}

打开行为树demo,可以看到该行为树如下图所示:

为了在程序启动时,等待编辑器连接上才往后继续执行,需要在tutorial_7.cpp文件中的InitBehaviac方法中,添加如下代码:

behaviac::Config::SetSocketBlocking(true);

如果需要修改端口号,需要添加如下代码:

behaviac::Config::SetSocketPort(60636);

为了在连调时,程序端能够发送消息到编辑器端,需要在游戏循环中执行Workspace::DebugUpdate()方法,如下代码所示:

voidUpdateLoop(){LOGI("UpdateLoop\n");intframes=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。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/7/14 18:03:10

Week 29: 深度学习补遗:MoE的稳定性机制与路由策略实现

文章目录Week 29: 深度学习补遗&#xff1a;MoE的稳定性机制与路由策略实现摘要Abstract1. Noisy Top-K Router1.1 理论背景1.2 代码实现2. Token 级与 Pooling 级路由2.1 理论背景2.2 代码实现3. Auxiliary Loss3.1 理论背景3.2 代码实现总结Week 29: 深度学习补遗&#xff1a…

作者头像 李华
网站建设 2026/7/14 18:03:09

25年12月14日复盘总结,大盘方向,操作建议,板块机会,实用干货

25年12月14日复盘总结&#xff0c;大盘方向&#xff0c;操作建议&#xff0c;板块机会&#xff0c;实用干货大盘指数经过近一个季度回调半指的风险得到了极大的释放&#xff0c;指数走出了三段4的调整&#xff0c;那在这个位置我们就不应该再看风险&#xff0c;三段4的调整已经…

作者头像 李华
网站建设 2026/7/14 18:03:07

what?动态规划?

动态规划入门&#xff1a;从原理到实战&#xff0c;吃透基础算法动态规划&#xff08;Dynamic Programming&#xff0c;简称 DP&#xff09;是算法领域的核心思想之一&#xff0c;也是面试、竞赛中的高频考点。它并非单一算法&#xff0c;而是一种 “化繁为简” 的解题思路 ——…

作者头像 李华
网站建设 2026/7/14 18:03:04

CommonJS 的缓存机制:为什么二次 require 得到的对象是同一个?

各位同仁&#xff0c;下午好&#xff01;今天&#xff0c;我们将深入探讨 Node.js 中 CommonJS 模块系统的核心机制之一&#xff1a;模块缓存。这是一个看似简单却蕴含深厚设计哲学的机制&#xff0c;它直接决定了我们在 Node.js 应用中管理状态、优化性能以及理解模块行为的关…

作者头像 李华
网站建设 2026/7/14 18:03:03

跨标签页通信的五种方案:LocalStorage、BroadcastChannel 与 SharedWorker

各位同仁&#xff0c;下午好&#xff01;今天&#xff0c;我们将深入探讨前端开发中一个既常见又关键的议题&#xff1a;跨标签页通信。在现代Web应用中&#xff0c;用户经常会同时打开多个标签页或窗口来访问同一个网站的不同部分&#xff0c;或者处理同一任务的不同阶段。在这…

作者头像 李华