Skip to content

Run Behavior Tree, AIController Setup, and Blackboard Keys

At a glance

Lives in: Blueprint API / AI - Target: an AIController - Input: BTAsset, the Behavior Tree asset to run - Returns: Boolean return value for whether the run request started successfully - Can fail by: invalid target/controller, missing Behavior Tree asset, bad or incompatible Blackboard setup, wrong pawn possession path, or later task failures after the tree has started - Official docs: Run Behavior Tree, Use Blackboard, and Behavior Tree User Guide

The one-minute version

  • Run Behavior Tree is called on an AIController, usually from the controller's On Possess or BeginPlay setup path.
  • The node starts the specified Behavior Tree on that controller's AI brain. It does not spawn the pawn, possess the pawn, create a NavMesh, sense the player, or choose blackboard values for you.
  • The Boolean return value only tells you whether the tree run request started successfully. It does not mean every task, move, attack, or decorator will later succeed.
  • Your enemy pawn should have AI Controller Class set to your AIController Blueprint and Auto Possess AI set correctly for placed/spawned enemies.
  • Create the Blackboard keys first, assign that Blackboard to the Behavior Tree, then set key values from the AIController, perception events, services, or tasks.
  • Perception should update blackboard facts such as TargetActor, HasLineOfSight, and LastKnownLocation; the Behavior Tree should react to those facts.

What it actually does

At beginner altitude, Run Behavior Tree asks an AIController to start a Behavior Tree asset:

pseudocode of the engine relationship - not engine source

AIController.RunBehaviorTree(BT_Enemy):
    if controller or BT asset is invalid:
        return false

    make sure the controller has behavior tree/blackboard runtime components
    initialize the tree's blackboard if the tree uses one
    start the tree through the controller's brain component
    return whether the start request was accepted

After that, the tree owns its own running logic:

tree starts
-> decorators read blackboard keys
-> active branch runs tasks
-> Move To task asks AI/path following to move the controlled pawn
-> tasks later succeed, fail, or keep running

So a true return means "the controller accepted the tree start," not "the AI will definitely walk to the player and attack."

The setup checklist

For a normal beginner enemy:

Assets:
    BB_Enemy
        TargetActor (Object, base Actor or Pawn)
        LastKnownLocation (Vector)
        HomeLocation (Vector)
        HasLineOfSight (Bool)
        PatrolLocation (Vector)
        AttackRange (Float)

    BT_Enemy
        Blackboard Asset = BB_Enemy

    BP_EnemyAIController
        Event On Possess
        -> Run Behavior Tree BT_Enemy

    BP_EnemyCharacter
        AI Controller Class = BP_EnemyAIController
        Auto Possess AI = Placed in World or Spawned

Level:
    NavMeshBoundsVolume covers enemy and goals

When spawned at runtime, make sure the spawn path actually creates/assigns an AIController. Using correct pawn defaults, Spawn AI From Class, or an explicit Spawn Default Controller are common ways to avoid an unpossessed AI pawn.

Where to call it

The clean first place is the AIController:

BP_EnemyAIController
-> Event On Possess(NewPawn)
-> Run Behavior Tree (BTAsset = BT_Enemy)
-> Branch Return Value
   true:
       set initial blackboard keys
   false:
       Print String "Run Behavior Tree failed"

On Possess is useful because the controller-pawn link exists by then. Tasks that need Get Controlled Pawn now have the body they are supposed to control.

BeginPlay can also work when the controller already has its pawn, but it is easier to get timing wrong with spawned enemies. If you call from BeginPlay, print Get Controlled Pawn while debugging.

Avoid starting the tree from a random level actor, widget, or sensing event. Those can work only after they find the correct AIController instance. The controller already is the owner of the AI brain, so make it the normal setup home.

The target pin

The target is the AIController.

Inside BP_EnemyAIController, Self is usually correct:

Self -> Run Behavior Tree

Inside BP_EnemyCharacter, you need the controller:

Get Controller
-> Cast to BP_EnemyAIController
-> Run Behavior Tree

That can work, but it is usually the noisier ownership direction. The pawn is the body. Let the AIController start its own brain when it possesses the body.

The BTAsset input

BTAsset is the Behavior Tree asset you want this controller to run.

If the pin is None, the run request cannot do useful work. Branch on the Boolean return and print during setup:

Run Behavior Tree BT_Enemy
-> Branch Return Value
   false:
       Print String "BT_Enemy did not start on " + Get Display Name(Self)

Do not call Run Behavior Tree every Tick or every perception update. Start the tree once for the AI, then update blackboard keys as facts change.

The Boolean return value

The return value is about the start request.

true means:

  • the controller accepted the tree start;
  • the tree can begin executing through the AI brain/Behavior Tree component;
  • the setup was valid enough to start.

false means:

  • the controller could not start that tree in this setup;
  • common causes include missing asset, invalid runtime components, or blackboard setup that cannot initialize for the tree.

It does not mean:

  • the AI has a target;
  • a Move To task found a path;
  • a decorator is true;
  • a custom task finished correctly;
  • an attack animation played;
  • the pawn is alive and movable forever.

Treat it like this:

Run Behavior Tree
-> Branch Return Value
   true:
       Continue setup
   false:
       Print controller, BT asset, controlled pawn, and blackboard asset

Then debug later behavior inside the Behavior Tree, Blackboard, Move To task, perception, and NavMesh.

Blackboard asset and keys

Create the Blackboard before building the tree:

BB_Enemy
    TargetActor: Object, base class Actor or Pawn
    LastKnownLocation: Vector
    HomeLocation: Vector
    HasLineOfSight: Bool
    PatrolLocation: Vector
    AttackRange: Float

Then assign BB_Enemy in the Behavior Tree's root/details panel. If the tree does not know which Blackboard it uses, decorators and tasks cannot reliably offer or read the keys you expect.

Key names and key types must match the nodes that use them:

Set Blackboard Value as Object
    Key Name = TargetActor
    Value = PlayerPawn

Move To task
    Blackboard Key = TargetActor

If TargetActor was created as a Vector key, setting it as an Object is the wrong operation. If the object key's base class is too narrow, a valid target actor may be rejected or unusable in the places you expect.

Use Blackboard

Use Blackboard is the lower-level setup node that tells an AIController to use a Blackboard asset and gives you a Blackboard Component reference.

Beginner projects often let Run Behavior Tree initialize the Blackboard that the tree references. Calling Use Blackboard explicitly can still be useful when you want to prove setup or store the component:

Event On Possess
-> Use Blackboard(BB_Enemy)
-> Branch Return Value
   true:
       promote Blackboard Component
       Run Behavior Tree(BT_Enemy)
   false:
       print "Use Blackboard failed"

Do not use Use Blackboard with one asset and run a Behavior Tree that expects a different Blackboard unless you know exactly why. Key mismatch bugs are hard to read from the tree alone.

Set initial keys after start

Set stable initial values after the controller has a Blackboard component:

Run Behavior Tree returns true
-> Get Blackboard Component
-> Set Value as Float AttackRange = 175.0
-> Set Value as Vector HomeLocation = controlled pawn location
-> Set Value as Object TargetActor = None

Some teams set initial values before starting the tree after Use Blackboard succeeds. That can also work. The beginner rule is simpler: prove the Blackboard component exists, then set keys on that component, then debug those values in the Behavior Tree debugger.

Perception should set keys

Perception events should not directly run every behavior. They should update facts.

Good shape:

AI Perception: On Target Perception Updated(Actor, Stimulus)
-> Break AI Stimulus
-> Branch Successfully Sensed
   true:
       Set Blackboard Value as Object TargetActor = Actor
       Set Blackboard Value as Bool HasLineOfSight = true
       Set Blackboard Value as Vector LastKnownLocation = Actor location
   false:
       Set HasLineOfSight = false
       Set LastKnownLocation = Stimulus Location
       maybe start/refresh forget timer

Then the Behavior Tree reacts:

Selector
-> Chase branch
   Decorator: TargetActor is set
-> Search branch
   Decorator: LastKnownLocation is set
-> Patrol branch

That separation avoids restarting or duplicating AI behavior every time a sense updates. Sensing changes blackboard state. The tree chooses the active branch.

Controlled pawn requirements

Run Behavior Tree targets the controller, but most useful tree work still needs a controlled pawn.

Examples:

  • Move To tasks need a pawn/body to move.
  • Attack tasks need a pawn/character/combat component to call.
  • Perception setup often depends on which pawn the controller owns.
  • Home/patrol locations may be initialized from the pawn's location.

If there is no controlled pawn:

Run Behavior Tree may not be the first thing that reports your real bug.
The tree can start far enough to fail later when tasks ask for the pawn.

So debug both:

On Possess
-> Print NewPawn
-> Run Behavior Tree
-> Print Return Value

And inside a custom task:

Event Receive Execute AI
-> Is Valid Controlled Pawn
   false: Finish Execute false

What the node does not do

  • It does not spawn or possess an enemy pawn.
  • It does not set the pawn's AI Controller Class.
  • It does not create a NavMesh or make Move To tasks succeed.
  • It does not sense the player.
  • It does not set TargetActor, PatrolLocation, or any other Blackboard key for you.
  • It does not make decorators true.
  • It does not make custom tasks call Finish Execute.
  • It does not replicate AI decisions to clients by itself.

When it fails (and what failure does)

Symptom Likely cause
Return Value is false Missing/invalid BTAsset, invalid AIController target, or Blackboard/component setup could not initialize for that tree.
Return Value is true but enemy stands still Tree started, but active branch has no valid task, target, NavMesh, controlled pawn, or movement path.
Get Blackboard Component is None Blackboard was not initialized, wrong controller instance is being inspected, or setup failed before component creation.
Key-setting nodes appear to do nothing Wrong key name/type, wrong Blackboard asset, or setting keys on the wrong AIController instance.
Behavior Tree says no branch is active Decorators block every branch or root/composite setup is incomplete.
Move To task fails No NavMesh, invalid target/location, pawn not controlled, pawn off navmesh, or movement component cannot move.
Perception sees player but tree ignores it Perception event set a controller variable, not the Blackboard key the tree reads.
Works for placed enemy but not spawned enemy Spawned pawn did not receive AIController, Auto Possess AI is wrong, or tree start runs before possession.
Works on listen server but not clients AI runs on the authoritative server; client UI/debug view may not own that AIController.

The node has no failed execution pin. Use the Boolean return, prints, and the Behavior Tree/AI debugger to identify the exact missing piece.

The pattern everyone actually uses

Controller setup:

BP_EnemyAIController

Event On Possess(NewPawn)
-> Run Behavior Tree(BT_Enemy)
-> Branch Return Value
   true:
       Get Blackboard Component
       Set AttackRange
       Set HomeLocation = NewPawn location
   false:
       Print "BT_Enemy failed to start"

Perception update:

On Target Perception Updated(Actor, Stimulus)
-> Is actor a valid player target?
-> Break AI Stimulus
-> if Successfully Sensed:
       Blackboard.TargetActor = Actor
       Blackboard.LastKnownLocation = Actor location
       Blackboard.HasLineOfSight = true
   else:
       Blackboard.HasLineOfSight = false
       Blackboard.LastKnownLocation = Stimulus Location

Tree structure:

Root
-> Selector
   -> Sequence Attack
      Decorator: TargetActor is set
      Decorator: InAttackRange true
      Task: AttackTarget
   -> Sequence Chase
      Decorator: TargetActor is set
      Task: Move To TargetActor
   -> Sequence Patrol
      Task: ChoosePatrolLocation
      Task: Move To PatrolLocation
      Task: Wait

That is enough to prove the architecture before adding services, observer aborts, search behavior, or multiple enemy types.

Lookalikes - which one do I want?

Node/tool Use when Watch out
Run Behavior Tree An AIController should start a Behavior Tree asset. Start success is not behavior success.
Use Blackboard You want to explicitly initialize a Blackboard asset and get its component. Must match the tree's expected Blackboard.
Get Blackboard Component Controller/task/service needs to set or read keys. None means setup/instance/timing is wrong.
Set Blackboard Value as Object/Vector/Bool A fact changed and the tree should react. Key name and key type must match the Blackboard.
AI Move To node A Blueprint event should request simple AI movement. Behavior Trees usually use a Move To task.
Behavior Tree Move To task Tree branch should move to a Blackboard actor/location key. Still needs NavMesh, valid pawn, and reachable goal.
Start Logic / Restart Logic / Stop Logic You are controlling an existing AI brain component's runtime state. Not the normal first setup node for starting a tree asset.

Rule of thumb: start the tree once from the AIController, update Blackboard keys as facts change, and debug later behavior in the tree instead of calling Run Behavior Tree again.

The C++ twin

For the curious, the same idea in C++ usually lives on the AIController (our own example code):

void ATrainingEnemyAIController::OnPossess(APawn* InPawn)
{
    Super::OnPossess(InPawn);

    if (!IsValid(BehaviorTreeAsset))
    {
        UE_LOG(LogTemp, Warning, TEXT("Missing behavior tree asset"));
        return;
    }

    if (!RunBehaviorTree(BehaviorTreeAsset))
    {
        UE_LOG(LogTemp, Warning, TEXT("Behavior tree failed to start"));
        return;
    }

    UBlackboardComponent* Blackboard = GetBlackboardComponent();
    if (IsValid(Blackboard) && IsValid(InPawn))
    {
        Blackboard->SetValueAsVector(
            TEXT("HomeLocation"),
            InPawn->GetActorLocation());
    }
}

The native call has the same beginner meaning: start the tree on this controller, then set up the facts the tree will read.

Going deeper