Aborts and Interrupts with Decorators


In this article, I’ll show you how to abort and interrupt a node with a behaviour tree decorator.

Prior knowledge

This tutorial requires knowledge of:

Preparing the tutorial project

Let’s prepare a project to practice this tutorial.

Operating environment

This tutorial is created in the following environment.

Unity 2019.4.40f1
Arbor 3.9.0

Preparing the Arbor3

If you haven’t already, you’ll need to purchase it from the Asset Store.
If you want to purchase, you can open the product page of the asset from the link below.

Create tutorial project

Create a project for the tutorial.

Project Name Arbor_BT_AbortFlags
Template 3D
Assets to import Arbor 3: FSM & BT Graph Editor

For information on creating projects and importing Arbor, please refer to “Preparation for using Arbor”.

Preparing to use behaviour trees

To use a behaviour tree, you need to add a BehaviourTree component to your GameObject.

Create a GameObject with a BehaviourTree component

  • Click the + button in Hierarchy.
  • Select “Arbor > BehaviourTree” from the menu.
GIF

Open the BehaviourTree component in ArborEditor

Edit the graph of the BehaviourTree component in the Arbor Editor window.

  • Select the BehaviourTree object created from Hierarchy.
  • Click the “Open Editor” button in the BehaviourTree component of the Inspector window.
GIF

Abort a running node

If you can abort the node, you will be able to create NPCs that act flexibly.

For example, if an NPC is moving to pick up an item and another character picks it up first, we often want the NPC to switch to another action without waiting for the movement to complete.
Such abort conditions are determined by decorators.

Let’s build a behaviour tree that aborts a node.

Creating a Selector Composite Node

Create a Selector Composite node on a child node of Root.

  • Drag the slot at the bottom of the Root node (hereafter referred to as the child slot).
  • Drop below the root node.
  • Select “Create Composite” from the menu.
  • Select “Selector” from the composite selection window.
  • Confirm the name with the Enter key.
GIF

Create an Idle action node

Create an Idle action node in the Selector’s child node.

Idle is an action that does nothing.
It will continue to run unless aborted by a decorator or the like.
See the Arbor document “Idle” for details.

  • Drag the child slot of the Selector node.
  • Drop below the Selector node.
  • Select “Create Action” from the menu.
  • Select “Idle” from the action selection window.
  • Change the name to “Idle1” and confirm with the Enter key.
GIF

Duplicate Idle1 node

Add another Idle action to the Selector’s child node.

  • Click the settings icon for the Idle1 node.
  • Select “Duplicate” from the menu.
  • Double-click the name part of the duplicated Idle1 node (node on the right).
  • Change the name to “Idle2” and confirm with the Enter key.
GIF

Add CalculatorCheck decorator

Add a CalculatorCheck decorator to the Idle1 node.

  • Point the mouse at the center of the gap between the header of the Idle1 node and the title bar of the action.
  • Click the “Insert Decorator” button that appears.
  • Select “Add Decorator” from the menu.
  • Select “CalculatorCheck” from the decorator selection window.
GIF

About AbortFlags

After adding CalculatorCheck, you will see a dropdown labeled “Nothing” at the top of the decorator field.

This is the setting for aborting or interrupting the node depending on the decision result of the decorator.

Arbor calls this setting AbortFlags.
The types of flags that can be set are as follows.

  • Self
    A self-node or a subordinate node performs conditional judgment during execution.
    Execution continues while the result of the conditional judgment is true, and if it becomes false, it aborts and returns failure to the parent node.
  • LowerPriority
    A node with a lower priority than its own node performs conditional judgment during execution.
    If the result of the conditional judgment is true, abort the running node and start executing the own node.

AbortFlags is in bit flag format, and both Self and LowerPriority can be set in combination.
Also, regardless of AbortFlags, conditional judgment is performed once when the node is executed, and if the judgment result is false, failure is returned to the parent node without being executed.

Setting AbortFlags

This time we want to abort the Idle1 node while it is running, so we set AbortFlags to Self.

  • Click the AbortFlags dropdown for CalculatorCheck.
  • Select only “Self” from the menu.
GIF

CalculatorCheck settings

Configure settings other than AbortFlags.

  • Click the + button in Condition List.
  • Select “Bool” from the menu.
  • Turn on the check for Bool Value 1.
GIF

Let’s see how it works

Let’s play and check the operation.

First, let’s see how it works without doing anything.

Only Idle1 continues to run.
The flow of this operation is as follows.

  • Root node is executed first.
    Root node forces execution of only one child node.
  • Selector node is executed.
    Selector nodes are executed in order from the leftmost child node.
  • CalculatorCheck of the Idle1 node determines the execution condition.
    Execute the action because the Boolean values match.
  • The Idle action on the Idle1 node does nothing.
    It does not return success or failure, so the Idle1 node continues running.

Let’s turn off the check of CalculatorCheck’s Bool Value 1 while playing.

GIF

The Idle2 node is now running.
The flow of operations has changed as follows.

  • Condition of CalculatorCheck becomes false while Idle1 node is running.
  • Since CalculatorCheck’s AbortFlags is Self, it returns its own node as a failure.
  • Since the result of the Idle1 node was a failure, the Selector executes the node on the right.
  • Idle2 node is running.
    Idle actions continue to run without doing anything.

Now, when AbortFlags is Self, we have confirmed that the running node is aborted when the decorator’s judgment result becomes false.

Node interruption

If you interrupt a certain action with a high-priority action, you can make the NPC act more flexibly.

For example, security guards may be patrolling routes on a regular basis, or they may be waiting in a security office.
However, regardless of the behavior, I would like you to give top priority to tracking suspicious persons as soon as they are found.

Interrupts can be realized by making a small change to the behaviour tree we have created so far.

Change AbortFlags

Set CalculatorCheck’s AbortFlags to LowerPriority.

  • Click the AbortFlags dropdown for CalculatorCheck.
  • Select “Nothing” from the menu (deactivate “Self”)
  • Click the AbortFlags dropdown on CalculatorCheck again.
  • Select “Lower Priority” from the menu.
GIF

Change CalculatorCheck

Since we want to run the Idle2 node with the lowest priority first, change the CalculatorCheck condition so that it does not match.

  • Uncheck Bool Value 1.

Let’s check the operation

Let’s play and check the operation.

First, let’s see how it works without doing anything.

Only the Idle2 node keeps running.

The flow of this operation is as follows.

  • Root node is executed first.
    Root node forces execution of only one child node.
  • Selector node is executed.
    Selector nodes are executed in order from the leftmost child node.
  • CalculatorCheck of the Idle1 node determines the execution condition.
    The result is false because the Bool values do not match, returning failure to the parent node without executing the Idle1 node.
  • Since the result of the Idle1 node was a failure, the Selector executes the node on the right.
  • Idle2 node is running.
    Idle actions continue to run without doing anything.

Let’s turn on the check of CalculatorCheck’s Bool Value 1 while playing.

GIF

The Idle1 node is now running.
The flow of operations has changed as follows.

  • CalculatorCheck of the Idle1 node is re-evaluated while the Idle2 node is running.
  • The judgment result of CalculatorCheck of the Idle1 node becomes true.
    Since the running Idle2 node has a lower priority than the Idle1 node, Idle1 node is interrupted according to the LowerPriority setting of AbortFlags.
  • Idle2 node is aborted.
  • The Idle1 node runs on interrupt.
    The associated Idle action is executed.
  • Idle action does nothing.
    It does not return success or failure, so the Idle1 node continues running.

I was able to preempt a higher priority node than a lower priority node and run it.

Combining Aborts and Interrupts

AbortFlags Self and LowerPriority can be used in combination.

When combined, they allow interrupts and aborts to occur under the same conditions.

For example, security guards will track down a suspicious person, and if they leave, they will patrol or return to the security room.

Change AbortFlags

Add both Self and LowerPriority to CalculatorCheck’s AbortFlags.

  • Click the AbortFlags dropdown for CalculatorCheck.
  • Select “Self” from the menu.
    Both “Self” and “LowerPriority” are selected.
    (This is the same as selecting “Everything”.)
GIF

Operation check

Let’s play and check the operation.

Try toggling the check on/off for Bool Value 1 in CalculatorCheck.

GIF

The flow of operation is as follows.

  • When the judgment result of CalculatorCheck is true, Idle1 is executed.
  • When the judgment result of CalculatorCheck is false, Idle2 is executed.

Every time the judgment result of CalculatorCheck changed, it was confirmed that an abort or an interrupt was immediately performed.

Supplement to LowerPriority

LowerPriority, as the name suggests, is a setting that interrupts a node with a low priority and interrupts a node with a high priority.
In other words, if the priority is lower than the node for which LowerPriority is set, there is a possibility that the node with the higher priority will be interrupted regardless of the number of processing contents.

For example, let’s say you have a behaviour tree like this:

The flow of operation is as follows.

  • If the Idle1 condition is false, run the Wait node for 10 seconds, then the Idle2 node.
  • When Idle1’s condition becomes true, Idle1 is interrupted and executed regardless of whether the Wait node or Idle2 node is running.

In the security guard example, Idle1 is the chase action, and Wait and Idle2 are patrol and wait actions.
Tracking action is executed with the highest priority when a suspicious person is found, whether it is patrol or waiting.

It is easy to understand which node to suspend from the node set with LowerPriority by comparing the priority of the nodes.

  • Root : 0
  • Selector : 1
  • Idle1 : 2
  • Sequencer : 3
  • Wait : 4
  • Idle2 : 5

In other words, Sequencer, Wait, and Idle2 of nodes lower than priority 2 of Idle1 (larger numbers) will be interrupted by Idle1.

End

This concludes the Arbor tutorial “Aborts and Interrupts with Decorators”.

Tweet completion of tutorial

See other tutorials