Decorators

Decorator nodes (also known as conditionals) are attached to either a Composite or Task node. Decorator nodes make decisions on whether a branch in the Behavior Tree, or even a single node, can be executed. In their essence, they are a condition; they check whether something should be occurring. In other words, a Decorator can check whether it is worthwhile continuing on that branch and can report a preventive Failure if, based on a condition, we know for sure that the Task (or the sub-tree) will fail. This will avoid the Decorator trying to perform a Task (or sub-tree) that is impossible (for any reason: lack of information, the goal is no longer relevant, etc...).

In general, Decorator nodes can assume the role of a Gate between the parent and the rest of the sub-tree. Thus, Decorators have the power to loop the sub-tree until a certain condition is met, or to not make execute within that sub-tree until a specific timer has expired, or even change the return result of the Sub-Tree.

For a (simple) example, imagine that there is a sub-tree dedicated to killing the player (it will make decisions so that the Agent will try and kill the player). Checking if the player is in range (and not from the other side of the map), or even if the player is still alive, might give us a preventive fail without us even having to execute that sub-tree. Consequently, the tree can continue with other events or parts of the tree, for example, in another sub-tree, which will be responsible for the wander behavior.

Decorators can have parameters (which you will be able to set in the Details Panel once a Decorator has been selected), and usually they are either hard-coded values or Blackboard Key references (more on Blackboards later in this chapter).

Almost every Decorator has a checkbox in its parameters that allows you to invert the conditions (as a result, you will have more freedom, and you can use the same decorator on two different parts of the tree to execute different conditions).

The following screenshot shows how a decorator can be attached to a Composite node. Note that it is possible to have more than one Decorator per node:

For those who are familiar with Conditional nodes in other Behavior Tree systems, it is important not to confuse them with Task leaf nodes in Unreal Engine. More information can be found at  https://docs.unrealengine.com/en-us/Engine/AI/BehaviorTrees/HowUE4BehaviorTreesDiffer.

Like Tasks, Unreal comes with some built-in Decorators that are ready to be used. They are general and cover the basic cases that you will probably need, but obviously, they cannot be specific for your game or application, and so you will need to create your own Decorators (we will look at this in detail in Chapter 6, Extending Behavior Trees).

Here is the list of the built-in tasks in Unreal:

  • Blackboard: Checks if a specific key on the Blackboard Is Set (or Is Not Set).
  • Check Gameplay Tags on Actor: As the name suggests, it checks if there is a specific Gameplay Tag(s) on an Actor that's been specified by a Blackboard value.
  • Compare BBEntries: Compares two Blackboard values and checks if they are equal (or not equal) to each other.
  • Composite: This allows you to compose different Decorators at once with boolean logic. Once you have placed this Decorator, you can open its editor by double-clicking on it. From there, you will be able to build a graph with boolean operators and other Decorators.
  • Conditional Loop: As long as the condition is satisfied (whether a Blackboard Key Is Set or Is Not Set), it will keep looping through the sub-tree.
  • Cone Check: This checks if one point (usually another Actor) is within a cone, starting from another point (usually the AI agent); the cone angle and direction can be changed. An example of its use is if you want to check whether the Player is in front of the enemy or not—you could use this code to determine this condition.
  • Cooldown: Once the execution exits from the branch containing this Decorator, a Cooldown timer will start, and this Decorator doesn't allow the execution to enter again until this timer has expired (it reports Failure immediately). This node is used so that you don't repeat the same sub-tree too frequently.
  • Does Path Exist: This uses the Navigation System (more on this in Chapter 3, Navigation) to determine (and check) whether or not a Path exists for a specific point.
  • Force Success: As the name suggests, it forces the Success of the sub-tree, regardless of whether a Failure (or a Success) has been reported from below. This is useful for creating optional branches in a Sequence.
Note that Force Failure doesn't exist, since it wouldn't make sense. If this were to be placed on a Selection, this would make it a Sequence, and if it were placed on a Sequence, it would only make one child execute.
  • Is at Location: As the name suggests, it checks if the Pawn is (near or) at a specific Location (optionally, using the Navigation System).
  • Is BBEntry of Class:As the name suggests, it checks if a specific Blackboard Entry is of a specific Class. This is useful when the Blackboard Entry is of type Object, and you need to check if the reference within the Blackboard is of a specific class (or inherits from one).
  • Keep in Cone: Similar to Cone Check, this Decorator (continuously) checks if the Observer is within a Cone.
  • Loop: As the name suggests, it loops within the sub-tree for a specific number of times (or even an infinite number of times; in this case, something else is needed to stop the behavior of the sub-tree, e.g. another Decorator).
  • Set Tag Cooldown: Similar to its homonym Task, when this Decorator becomes relevant (or if you imagine it as a gate, when it is traversed), it will change the Cooldown timer for a specific Tag (see the following node).
  • Tag Cooldown: This is the same as the Cooldown node, but it has a timer associated with a Tag. As a result, this timer can be changed by the "Set Tag Cooldown" Task and by the "Set Tag Cooldown" Decorator.
  • Time Limit: As the name suggests, it provides a time limit for the sub-tree to finish its execution. Otherwise, this Decorator will stop execution and return a Failure.

Now that we have seen how Decorator nodes work, let's explore the last type of nodes of the Behavior Tree, Service nodes, which will continuously update and provide information in real time.