4

我在实现我的行为树时遇到问题。我想我了解基础知识,但我被正在运行的事件所困扰,特别是如何停止它们(或者更确切地说如何不停止它们)

假设以下简单树:

Tree
  while "talk_to_lady"
    sequence
      move_to_position
      talk
  while "dance"
    sequence
      dance_move_1
      dance_move_2

序列中的所有节点都是运行时间较长的动作,因此返回运行状态直到完成。

假设舞蹈是真的,角色会跳舞,这很好。现在talk_to_lady 为真,这意味着角色应该去那里与她交谈。虽然该任务确实具有更高的优先级并且我确实希望它发生,但我仍然希望让角色在移动到talk_to_lady while 循环之前完成当前的舞蹈节点(即动画)(尽管可能有其他情况我会不想等)。

我的解决方案是让树在 dance_move 动作上调用 Abort() 方法,但如果这返回运行状态,它将忽略 talk 动作,直到 dance_move 动作返回成功或失败。此外,如果树中较高优先级的事件是另一个动作而不是 while 节点,则它可能已经做出了可能干扰 dance_move 动作的状态更改。

我是否遗漏了什么,或者有没有我没有读过的解决方案?

4

2 回答 2

0

您可以在“talk_to_lady”之上添加一个条件节点。作为装饰器的条件节点提供了一个只有舞蹈完成的条件,然后执行“与女士交谈”行为。

Tree
  condition: "dance state" == "finish" 
    while "talk_to_lady"
      sequence
        move_to_position
        talk
  while "dance"
    sequence
      dance_move_1
      dance_move_2
于 2020-10-29T05:27:42.313 回答
0

IMO,您必须拥有另一个单独的侦听器函数,该函数将协调其他函数的执行或在其自己的线程中运行每个函数,而忽略导致问题的“同步”机制。现在,根据所使用的语言,实现这一点可能非常简单或非常重要。通过使用多线程方法,我将函数设置为在它们各自的线程中执行,从而使您能够根据自己的意愿从主线程停止线程,主线程实际上是您的事件侦听器/生成器。您可以有一个辅助类,它将在您的主线程中实例化,例如ThreadManager或类似的东西,它们将嵌套用于管理正在运行的线程(您的函数)的方法和对象/数组。

因此,主线程将捕获发出的事件,通过您的ThreadManager类生成新线程,并在触发具有更高“等级”的事件时停止它们。如果您想在某些情况下保持同步性(如果新任务不应该中断当前正在运行的任务),您可以将函数调用设置在队列中。

这可能需要你一些时间来设置,但最终可能会得到回报,我个人在 Python 中使用过这个模型来处理类似的用例,并且效果很好。

于 2018-08-20T11:51:18.633 回答