How to create a Low-Priority/Self Abort Workflow?

Hello all :wave:

First of all, I wanted to state that I’m elated to see Behavior Graph implemented into Unity. I’ve been hoping a tool like this would be built in for a while now. With how approachable and modern the UI/UX is, I’m surprised I don’t see more buzz around this addition.

I’ve been playing around with the graph designer and my experience with it has been positive so far. However, I was wondering if there was a way to add the ability to abort a lower-priority node from a prior node in the branch as in other behavior tree implementations. As far as I can tell this functionality is not in Behavior Graph currently. I understand there’s an Abort modifier node but it seems that the abort that’s triggered would either cause the entire branch to fail or continue to the next node depending on the setup. Below is my attempt at using it:

I saw another user in this forum come to a similar conclusion so I’m not sure If I’m missing something.

I’m not an expert in behavior trees either. So, if anyone knows an alternate way to get a similar flow going to lower-priority/self aborts in Behavior Graph that would be appreciated!

If someone on the staff could state whether node specific aborts could be implemented in the future, that would also be cool!

Hi @mockah

  • I’m not sure to understand how a lower-priority would work in that case. Would be nice if you could describe how this would work and what would be the expected outcome.
  • By self abort, do you mean an additional parameter or setting on the node that would allows to abort/stop a node that is Running or Waiting?
    • If so, this would generally be node specific and nothing prevents you from creating your own custom node with such behavior.

From the provided example, my understanding is that you would like a way to abort the patrol after a certain time - aka a Timeout on this particular node, so for this particular example, you could do something like:

In case you are trying to create a more advance behavior that could be splits into states and would like/need more advance condition to describe such state changes, I would recommend to take a finite state machine approach, i.e.:

But nothing prevents you from combining both approach, the tool is very flexible and you could even decouple a state machine using EventChannel while keeping the state evaluation approach of a BT to update the states.

I hope this will helps.
Please don’t hesitate if you have more question or want to provide more use case examples :slightly_smiling_face:

Hi Morgan, thank you for the response.

Apologies, as I attempted to make a simple example but I oversimplified some details a bit. I also got some of my wording confused as well as I was referencing how multiple behavior tree systems handle this feature (e.g., Unreal Engine’s Behvaior Tree, Opsive’s Behavior Designer).

From my previous example, yes, adding a Time Out modifier would work just as fine.

I made a new tree that is more in line with what I’m looking to achieve and am hoping is a bit more practical. This example is loosely based on one of Unreal Engine’s Behavior Tree Tutorial videos:

In this graph, the agent will typically spawn and begin patrolling from its 4th branch as the initial sibling’s conditions aren’t met. If the agent hears a noise the 3rd branch will abort the lower priority patrolling branch and then begin to execute the investigate noise branch. If the player is within the agent’s line of sight, regardless of whether the patrolling or investigating branch is running, they will be aborted and the attacking branch will execute. Finally, if the conditions are met for the 1st branch to get ammo, it will also abort any running nodes to the right of it and execute.

As a side note, when I attempted to create my own Abort modifier when trying to implement the IConditional interface I got the following error:

'IConditional' is inaccessible due to its protection level (CS0122)
interface Unity.Behavior.IConditional

As a result, I was unable to find a way to configure conditions on my custom modifier despite setting up the conditions attributes.

I’m not all that familiar with Behavior Graph’s code so I can only write in pseudo-code for the time being for the logic I’m hoping to achieve inside AbortLowerPriorityModifier:

public partial class AbortLowerPriorityIfModifier : Modifier, IConditional
{
    // ...

    private void OnAbortLowerConditionMet() {
        AbortLowerPrioritySibling();
    }

    private void AbortLowerPrioritySibling()
    {
        // Find the active sibling
        // Graph.GatherActiveNodes(this, out HashSet<Node> outCollection);
        // Node currentRunningSibling = outCollection.FirstOrDefault(); // Need to filter for nodes with the same parent as this

        // End the current running sibling
        // Graph.EndNode(currentRunningSibling);

        // Start running the branch from here
        // Graph.AwakeNode(this);
    }

    // ...
}

Again I do run into more inaccessible errors for the Node’s Graph field as a few other fields and methods used in AbortModifier.cs. I’m a little bit novice in figuring out how to work around this currently.

Again, apologies! I got a little confused with my wording. In Unreal Engine, a decorator can have a self-abort event where it’s able to abort itself and any running children and then return a failure. The Abort modifier already does this! So essentially, what I’m really looking for here is the lower-priority abort feature where a decorator can abort a running sibling node to its right.

An FSM would definitely achieve the results I’m looking for and that might be the system I’ll roll with as I continue to try out Behavior Graph.

My concern is that as the graph grows, the need to create more logic and conditions to determine which state should be active also grows and becomes hard to maintain as is usually the case. I would prefer to keep the advantage of working with the flow of a behavior tree.

Hoping the details I provided are a bit more clear and that there could be a solution to achieving this feature.

Thank you for the information and suggestions you provided :waving_hand:

Hi mockah,

Thank you for taking the time to provide such a detailed explanation. I understand much better what you are trying to achieve.
There is a lot to unpack here but it all makes a lot of sense. I’ll share the details with the team and we will try to look at solution we can provide in the near future.

Exposing IConditional is something we was planning on doing once we would have more time to consolidate the API around it. We will let you know when this is released.

This is a fair statement and it sounds reasonable to me to try to provide a solid base allowing FSM and BT user from experiencing the tool in a familiar way if this is possible. I personally believe Behavior package really shine when using both approach together (evaluating state with BT and Running behavior with state machine - and I’m saying state machine instead of FSM because it is possible to dynamically expand the SM using RunSubgraph dynamically).

We are currently in the process of gathering the huge amount of user feedback to plan our roadmap, so this might take a bit of time before reaching this point (of having feature parity with other BT tools).

Thank you again for your feedback sorry for the inconvenience :bowing_man:

Hi Morgan,

Thank you for your response and thanks to you and the team for considering this feature! It would make migrating from previously made behavior tree designs towards Behavior Graph a smoother experience for me as I’m sure other designers.

I’m sure that despite Behavior being 1.0, it’s still in the midst of a lot of refactoring as you continue to adapt it from gathered feedback. From what I’ve used I can still say this is still an amazing tool in terms of it’s versatility among other features.

Thanks again and looking forward to future updates! :+1:

Hey, just checking in, are there any updates on this?

Hi @cuhodicamry,

Thanks for your interest!
Are you referring to exposing IConditional or more feature parity with traditional FSM and BT? Or anything more specific?

IConditional is still on the backlog as we have been focusing on bringing stability and QoL. I cannot give information in regards to the later however.

Sorry for not being able to bring more information at the moment :person_bowing:

Hi @MorganHoarauUnity
I’m referring to any features that could help achieve ‘Abort Lower Priority Nodes’ as mentioned above. From what I’ve read, IConditional might be the one.
Glad to hear that IConditional and more QoL features are being developed

Thank you!

I too am puzzled by the right way to implement this, is there an alternate pattern or any kind of node that could be implemented to make this more DRY? The enum variable switch approach could work, but requires external bookkeeping and as I mentioned in another thread there are currently some severe bugs with the switch node Behavior Package 1.0.10 Released! Changelog inside - #9 by wilgieseler.

Hi @wilgieseler

Unfortunately there isn’t for the time being.

I’ve had a quick glance as it’s been requested for a while now. Exposing IConditional won’t be enough as we also need an implementation for the authoring data (NodeModel, NodeUI and NodeUIInspector).

Apologies for the slight necro, but I’d just like to drop in here and say this would be my most requested feature. For me, it’s the one thing holding the behavior package back when stacked up against other implementations.

Even if Low Priority Aborts aren’t supported explicitly by Unity, exposing the necessary components so that the community can fill the gaps would be a massive benefit to the usefulness of the tool.

No question, just a humble request - thanks!

FYI