行为树::耗时超过一滴答的动作


19

根据我对行为树的了解,每个行为都应该是一个短期目标导向的动作,可以通过几次迭代来完成。

因此,例如,以下是行为树的图像:

在此处输入图片说明

现在让我们假设“ 驱逐敌人”行为在树中进行了多次迭代。因此,每次通过都会调用Drive To Enemy,因为它现在处于运行状态。

问题是如果附近有敌人,我想打电话给Evade Enemy。并考虑到驱动器要敌人总是叫我没有机会打电话给躲避敌人或许应该叫避开敌人)。

  • 无论当前正在执行什么操作,我都应该遍历Tree EACH通行证吗?
  • 我要这样做正确吗?
  • 处理此类行为的正确方法是什么?

最初在Stackoverflow上被问到。认为这里将是一个更合适的地方来问这个问题。


1
这里提供的答案有帮助吗?gamedev.stackexchange.com/questions/51693/...
四分

这也是我的问题。我本来打算将这个问题发表为评论,但我认为这应该是一个单独的问题。
自由蓝瑟

Answers:


16

看到我在以前的答案中提供的图像:

在此处输入图片说明

如果您想象节点1是'Evade Enemy'而节点2是'Chase Enemy',则即使在第二次迭代中(除了'2'和'B'都是绿色,第二次迭代时)开始),“逃避敌人”仍然会首先被检查。仅当“逃避敌人”失败时,因为附近没有敌人,才会再次激活“追逐敌人”。当再次访问“追逐敌人”时,它会注意到它处于“运行”状态,并直接跳到“ B”。

这意味着每次检查该树时,它将始终从左到右遍历。即使将一个节点标记为正在运行,仍会首先检查优先级较高的节点。

我不确定您是否要从右到左处理节点,但这就是您如何安排它们的方式(即在躲避敌人的情况下,将敌人定位在驱动器的右侧)。如果您需要进一步的说明,则应在聊天中或在有关该主题的现有问题中提问。


2
感谢您的另一个很好的解释。我很难理解行为树的递归性质。我想在最后一个问题的评论中问您,但不想将这些评论变成冗长的质量检查。最后一个问题是,这一切现在都说得通了。选择器和序列在处理运行状态方面有区别吗?似乎选择器(节点0)首先检查了节点1,而“节点2”序列没有在第二次迭代中检查节点A。
自由蓝瑟

4
好问题,我想你明白了。节点2未检查节点A,因为节点A已完成。当节点2标记为“正在运行”时,它指出节点B是当前正在运行的节点。您可以假设某个节点正在运行,这意味着无需再次检查先前的节点。
MichaelHouse

在第一次迭代后将根选择器(0)设置为“运行”后,是否要将根选择器(0)重置为“就绪”?
免费Lancer 2013年

我相信只有正在运行的节点的父节点设置为正在运行。需要将根设置为就绪,而不是运行,因为我们需要再次解析节点(1)。
MichaelHouse

3
那是一种选择。实际上,您可以根据需要频繁或不频繁地对其进行更新。如果需要,每300毫秒或每帧。或者,您可以具有固定的更新以及触发的更新来处理任何事件。与大多数此类结构一样,行为树没有严格定义。应该以最佳方式为您的游戏使用它们。如果评估每个帧都太浪费了,那就不要这样做。您还可以限制花在评估一棵树上的时间,如果需要,可以选择下一帧。有很多选择。
MichaelHouse
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.