Behaviour Trees and canceling running events

1.6k views Asked by At

I'm having issues implementing my behaviour tree. I think I understand the basics, but I am stuck with running events and specifically how to stop them (or rather how not to stop them)

Assume the following simple tree:

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

All of the nodes in the sequences are longer running actions, and thus return the running state until finished.

Assume dance is true, the character dances, which is fine. Now talk_to_lady is true, which means the character should go there and talk with her. While that task does have higher priority and I do want it to happen, I do still want to have the character finish the current dance node (i.e. an animation) before moving to the talk_to_lady while loop (though there might be other situations where I would not want to wait).

My solution would be to have the tree call a, say, Abort() method on the dance_move action, but if this returns the running state, it will ignore the talk action, until the dance_move action returns success or failure. Also, if the higher priority event in the tree is another action instead of a while node, it might already have made state changes that could interfere with the dance_move action.

Am I missing something or is there a solution to this I did not read about?

2

There are 2 answers

2
Milan Velebit On

IMO, you'll have to have an another, separate, listener function which would coordinate the execution of other functions or run each function in its own thread, disregarding the 'synchronous' mechanism which is causing the issue. Now, depending on the language used, it might be very trivial or very non-trivial to achieve that. By using the multithreading approach I'd set the functions to be executed in their respective threads, thus enabling you to stop threads at your will from the main thread which would actually be your event listener/spawner. You could have a helper class which would be instantiated in your main thread, say, a ThreadManager or something along the lines which would nest the methods and objects/arrays for managing running threads (your functions).

So, the main thread would catch the emitted events, spawn new threads via your ThreadManager class and stop them when an event with a higher 'rank' is fired. You could set the function calls in a queue if you want to retain synchronicity for certain situations (if a new task shouldn't interrupt the currently running one).

This could take you some time to set up but it could pay out in the end, I've personally used this model in Python for a similar use case and it worked very well.

0
Sunny Sun On

you can add a condition node on top of "talk_to_lady". the condition node as decorator provides a condition that only dance finishes, then execute " talk to lady" behavior.

Tree
  condition: "dance state" == "finish" 
    while "talk_to_lady"
      sequence
        move_to_position
        talk
  while "dance"
    sequence
      dance_move_1
      dance_move_2