Conditional Aborts

Conditional aborts allow your behavior tree to dynamically respond to changes without having to clutter your behavior tree with many Interrupt/Perform Interrupt tasks. This feature is similar to the Observer Aborts in Unreal Engine 4. Most behavior tree implementations reevaluate the entire tree every tick. Conditional aborts are an optimization to prevent having to rerun the entire tree. As a basic example, consider the following tree:

When this tree runs the Conditional task will return success and the Sequence task will start running the next child, the Wait task. The Wait task has a wait duration of 10 seconds. While the wait task is running, lets say that the conditional task changes changes state and now returns failure. If Conditional aborts are enabled, the Conditional task will issue an abort and stop the Wait task from running. The Conditional task will be reevaluated and the next task will run according to the standard behavior tree rules. Conditional aborts can be accessed from any Composite task:

There are four different abort types: None, Self, Lower Priority, and Both.

This is the default behavior. The Conditional task will not be reevaluated and no aborts will be issued.
SelfThis is a self contained abort type. The Conditional task can only abort an Action task if they both have the same parent Composite task.

Lower Priority
Behavior trees can be organized from more important tasks to least important. If a more important Conditional task changes status then can issue an abort that will stop the lower priority tasks from running.

This abort type combines both self and lower priority.

Conditional aborts can also be thought of the following way:

Lower Priority: will reevaluate when any task to the right of the current branch is active.
Self: will reevaluate when any task within the current branch is active.
Both: will reevaluate when any task to the right or within the current branch is active.

The following example will use the lower priority abort type:

In this example the parent Sequence task of the left branch has an abort type of lower priority. Lets say that the left branch fails and moves the tree onto the right branch due to the Selector parent task. While the right branch is running, the very first Conditional task changes status to success. Because the task status changed and the abort type was lower priority the Action task that is currently running gets aborted and the original Conditional task is rerun.

The conditional task’s execution status will have a repeater icon around the success or failure status to indicate that it is being reevaluated by a conditional abort:

Conditional aborts can be nested beneath one another as well. For example, you may want to run a branch when one of two conditions succeed, but they both don’t have to. In this example we will be using the Can See Object and Can Hear Object tasks. You want to run the action task when the object is either seen or heard. To do this, these two conditional tasks should be parented by a Selector with the lower priority abort type. The action task is then a sibling of the Selector task. A Sequence task is then parented to these two tasks because the action task should only run when either of the conditional tasks succeed. The Sequence task is set to a Lower Priority abort type so the two conditional tasks will continue to be reevaluated even when the tree is running a completely different branch.

The important thing to note with this tree is that the Selector task must have an abort type set to Lower Priority (or Both). If it does not have an abort type set then the two conditional tasks would not be reevaluated.