Controlling an NPC's Behavior with Dynamic Behavior Subtrees

This page will give an overview of how to utilize the Dynamic Subtrees in our standard behavior trees to modify an NPCs behavior. This page will not go into depth on the function and use of Behavior Trees in general, nor will it go over how to create your own behavior trees.

Behavior Subtrees

In a Behavior Tree you are able to run another tree as part of your behavior. This can be done by either using a RunBehavior task or a RunBehaviorDynamic task. Functionally they are both the same under the hood during a trees execution, the difference is that the RunBehaviorDynamic task allows you to modify what tree you target at runtime.

image-20240216-155845.png

Specifying a Subtree

Each RunBehaviorDynamic task has an Injection Tag field and a Default Behavior Asset field. The Example from the above selected task:

image-20240216-161259.png

Injection Tags

The InjectionTag field is used to denote tasks that should use the same subtree when modified at runtime. For example if you have multiple locations in your tree where you want to enter a “Passive” subtree, you would tag each of those with the same InjectionTag . These tags are defined as Gameplay Tags and the default ones can be found in the NPCGameplayTagTable .

Default Behavior Assets

The DefaultBehaviorAsset field is used to describe the default tree that should be run, if the tree is not modified at runtime. This default will apply to any Controller which does not modify them.

Defining Defaults per Controller

Our existing AI Controllers have a DefaultDynamicBehaviorTrees which is used when an NPC begins to run its behavior to set their default dynamic subtrees. The DefaultDynamicBehaviorTrees field is a map pairing FGameplayTag keys to UBehaviorTree values. Here you can define any Injection Tags you want to modify upon startup for instances of this controller, with the associated UBehaviorTree value being the new subtree.

When you are creating NPCs that you want to behave in their own specific way, creating a custom AI Controller based off of an existing one is the recommended approach. This lets you define the DefaultDynamicBehaviorTrees field while maintaining existing functionality.

The following is an example using our HumanAIController blueprint:

image-20240216-162006.png

In the case our NPC runs the BT_SimpleAttack Behavior Tree the Highlighted nodes will be modified, as their injection tags match those found in our Controller’s DefaultDynamicBehaviorTrees map.

image-20240216-162439.png

Setting a Dynamic Subtree at Runtime

We do not only have to operate by modifying the defaults found in the fields of our Controller or Behavior Tree, we are also able to change the subtrees at runtime. All that is needed to do this is a reference to our NPC’s Controller.

Functions for Managing Dynamic Subtrees

ResetAllBehaviorSubtreesToDefault

image-20240216-163350.png

ResetBehaviorSubtreesByTag

image-20240216-163537.png

SetBehaviorSubtree

image-20240216-163844.png

SetMultipleBehaviorSubtrees

image-20240216-164705.png

Order Matters

When you are setting multiple Subtrees it is important to note: the tasks associated with the injection tag you set will not be proactively set in the future. Should another subtree be injected that itself contains a task using the same tag as one you previously set, it will not automatically update the that task. The new dynamic task will run whatever it’s default set in the Behavior Tree task is unless otherwise overridden.