本文档描述的是3.6及以后版本,对于3.5及以前的老版本请参考分类“3.5”。
事件(Event)作为节点一种的附件,主要用于在程序端的游戏逻辑发出事件时,得到响应后打断当前正在执行的行为树,并切换到所设置的另一个行为树。
1. 添加类型信息及任务
在类型信息浏览器中为类“FirstAgent”添加了event_task(int param0)这个任务,或者更形象的称之为“接口”,该任务带有一个int类型的param0参数,如下图所示:
2. 创建带任务节点的子树
创建行为树subtree_task,该树根节点的第一个子节点务必是任务节点,并为其配置上面添加的任务event_task,如下三图所示:
在上面的行为树subtree_task中,ID为1的条件节点使用了任务event_task的参数param0。这类似于编程语言中的函数参数为函数体的代码提供了局部变量,任务节点中的参数也为当前的行为树提供了同名的局部变量,这些“局部变量”可以根据需要用于该行为树所有子节点,也就在行为树节点中使用了任务的参数。
3. 创建带有事件的主树
创建另一个行为树maintree_task,并将ID为4的动作节点的参数“决定状态的选项”设置为Running,用于模拟行为树一直持续执行在该动作节点上,如下二图所示:
接着,在编辑器左侧的行为树节点列表中,将行为树节点subtree_task通过鼠标拖拽到行为树maintree_task中的第一个序列节点上(注意:一般默认把事件附件放在根节点的第一个子节点上),这样该序列节点就有了一个事件附件,如下图所示:
然后,为该事件设置参数,如下图所示:
其中,“触发一次”表示该事件是否只触发一次就不再起作用。
“触发模式”控制该事件触发后对当前行为树的影响以及被触发的子树结束时应该如何恢复,有转移(Transfer)和返回(Return)两个选项:
- 转移:当子树结束时,当前行为树被中断和重置,该子树将被设置为当前行为树。
- 返回:当子树结束时,返回控制到之前打断的地方继续执行。当前行为树直接“压”到执行堆栈上而不被中断和重置,该子树被设置为当前行为树,当该子树结束时,原本的那棵行为树从执行堆栈上“弹出”,并从当初的节点恢复执行。
4. 程序端发送事件
最后,在程序端通过如下代码,将事件“event_task”发出,并指定所需的参数,如下代码所示:
g_FirstAgent->FireEvent("event_task", 2);
这样,在执行行为树maintree_task过程中,如果接收到事件event_task,那么该行为树中的事件附件event_task将得到响应和处理,行为树的执行就会从当前的maintree_task跳转到subtree_task。
注意:调用FireEvent的时候,只有处于Running状态的节点才会响应事件。这是为了允许不同分支在不同时机下,同样的事件可以触发不同的行为。比如同样是BeingHit,受伤或逃跑的时候可以分别对应不同的行为。如果不需要根据不同的节点响应不同的行为,只是需要响应事件,一般只需把事件配置在根节点的第一个子节点上(根节点同样需要是Running状态,非Running状态的节点没有机会响应事件)。
5. 执行行为树
执行行为树maintree_task,可以得到如下结果:
本教程对应的工作区和代码工程,请查看源码包中的目录tutorials/tutorial_6。