4

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?

SashaZd
  • 3,315
  • 1
  • 26
  • 48
cboe
  • 469
  • 1
  • 9
  • 25
  • Not sure if i'm getting it right -- wouldn't the current code finish the `dance` sequence before going to the `talk_to_lady` sequence? Or are you asking how to abort/continue depending on situation? – iamanigeeit Aug 20 '18 at 10:01
  • I would imagine the solution to be a queue or stack that contains the list of remaining actions to take – iamanigeeit Aug 20 '18 at 10:03
  • What language should your code be written in? The approach might differ – Milan Velebit Aug 20 '18 at 11:40
  • Sorry for the late reply - the way I understand is that these sequences always get checked from beginning to end, so if the first one returns success while the second one is running, it would abort the second one, which is not necessarily what I want. I'm writing in C# – cboe Aug 22 '18 at 10:50

2 Answers2

0

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.

Milan Velebit
  • 1,933
  • 2
  • 15
  • 32
  • Thanks, I like your thinking, but I fear threading is not an option and I do want to keep it simple. Also, my problem isn't really how to stop an action when a higher priority event is fired, but rather how I prevent that from happening while the current action is not finished. – cboe Aug 22 '18 at 10:52
  • Ah, I've now seen that I misunderstood that you actually want to retain a sort of synchronicity. I'd still say that this is one of the most viable options at hand. I've slightly edited my question. Seeing that you're using C#, you could fiddle around with using async/await but that's to a certain extent, I'd still say use threading, but I'm excited to see what others suggest, starred. – Milan Velebit Aug 22 '18 at 11:55
0

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
Sunny Sun
  • 65
  • 5
  • 13