Move To Task, Decorators, Services, and Observer Aborts¶
A Behavior Tree branch runs only when its conditions allow it. The Move To task is the action, decorators are the gates, services keep the facts fresh, and observer aborts decide how quickly the tree changes its mind.
At a glance
Use this for: Behavior Tree chase, patrol, search, and attack branches that depend on Blackboard keys - Main pieces: Move To task, Blackboard decorators, services, observer aborts, and branch priority - Beginner rule: tasks do work; decorators decide whether work is allowed; services update facts while a branch is active - Official docs: Behavior Tree Node Reference, Behavior Tree Tasks, Behavior Tree Decorators, and Behavior Tree Services
The one-minute version¶
- A Behavior Tree Move To task runs inside the tree and moves toward a
Blackboard key.
AI Move Tois a Blueprint node you call from an event graph. - A branch is eligible when its parent composite reaches it and its decorators
pass. A
Selectorusually tries higher-priority branches first. - A Blackboard decorator such as
TargetActor Is Setis a visible condition. If it fails, that branch is skipped or aborted. - A service runs while its attached branch is active, usually at a configured interval. Use it to update Blackboard facts such as distance, attack range, or last known location.
- Observer aborts make a branch react to watched Blackboard changes. Without them, a lower-priority branch can keep running until its current task ends.
Selfaborts the branch the decorator is attached to.Lower Priorityaborts lower-priority branches to the right.Bothdoes both.- Start with simple abort rules: chase condition on the chase branch usually
wants
Both; attack-range condition often wantsSelforBothdepending on your tree layout.
The relationship¶
flowchart TD
Root[Selector: AI Root]
Attack[Sequence: Attack]
Chase[Sequence: Chase]
Search[Sequence: Search]
Patrol[Sequence: Patrol]
Root --> Attack
Root --> Chase
Root --> Search
Root --> Patrol
Attack --> AttackDeco[Decorator: TargetActor set + InAttackRange]
Attack --> AttackTask[Task: AttackTarget]
Chase --> ChaseDeco[Decorator: TargetActor set]
Chase --> ChaseService[Service: update DistanceToTarget]
Chase --> ChaseMove[Move To: TargetActor]
Search --> SearchMove[Move To: LastKnownLocation]
Patrol --> PatrolMove[Move To: PatrolLocation]
The tree is not asking every branch to run at once. It is searching from the root, checking which branch is allowed, then running tasks in the selected branch.
Move To task vs AI Move To node¶
They use the same broad AI movement systems, but they belong in different places.
| Tool | Where it lives | Use it when |
|---|---|---|
| AI Move To | Normal Blueprint event graph. | A sensing event, custom event, or simple prototype should request one AI move and handle success/fail pins. |
| Behavior Tree Move To task | Behavior Tree graph. | A tree branch should move to a Blackboard actor or location key. |
The Behavior Tree Move To task does not have the same shape as the AI Move To
Blueprint node. It reads a Blackboard key:
Move To task
Blackboard Key = TargetActor
Acceptable Radius = 150
Or:
Move To task
Blackboard Key = PatrolLocation
Acceptable Radius = 75
That makes it tree-friendly. Perception or a patrol task changes the Blackboard key; the Move To task uses the current key value when it runs.
What Move To actually does¶
At beginner altitude:
pseudocode - not engine source
MoveToTask.Execute(AIController, Blackboard):
Goal = Blackboard.GetValue(BlackboardKey)
if Goal is invalid:
return Failed
Pawn = AIController.GetControlledPawn()
if Pawn is invalid:
return Failed
ask path following/navigation to move Pawn toward Goal
while move is active:
if close enough:
return Succeeded
if path fails, is aborted, or cannot complete:
return Failed or Aborted
The task still needs the same real-world setup as the AI Move To node:
- the controller must possess a pawn;
- the pawn must be movable;
- the level must have usable NavMesh for navigation moves;
- the start and goal should be on or projectable to the NavMesh;
- the target actor/location must be valid.
The task is selected by the Behavior Tree, but movement is still done through AI controller/path-following/navigation systems.
Move To settings that matter¶
| Setting | Beginner meaning |
|---|---|
| Blackboard Key | The actor or vector key the task should move toward. |
| Acceptable Radius | How close is close enough for task success. |
| Allow Partial Path | Whether an incomplete path can still be accepted. |
| Track Moving Goal | Whether movement should keep following a moving actor goal. |
| Project Goal Location | Whether the goal should be projected onto the NavMesh. |
| Observe Blackboard Value | Whether a changed goal key should redirect the active move. |
| Reach Test Includes Agent Radius | Whether the pawn capsule radius helps count arrival. |
| Reach Test Includes Goal Radius | Whether the goal actor radius helps count arrival. |
For a first chase branch:
Move To
Blackboard Key = TargetActor
Acceptable Radius = AttackRange or 150
Track Moving Goal = true
Observe Blackboard Value = true
For a first patrol branch:
Move To
Blackboard Key = PatrolLocation
Acceptable Radius = 75
Track Moving Goal = false
If a chase keeps stopping too early or never succeeding, inspect acceptable radius and reach-test settings before assuming the Behavior Tree is wrong.
Branch eligibility¶
A branch is eligible only when the tree reaches it and its conditions pass.
For a selector:
Selector AI Root
-> Attack branch
-> Chase branch
-> Search branch
-> Patrol branch
The left-to-right order is priority. The attack branch should usually sit left of chase, and chase left of patrol.
Decorator examples:
Attack branch:
TargetActor Is Set
InAttackRange == true
Chase branch:
TargetActor Is Set
Search branch:
LastKnownLocation Is Set
TargetActor Is Not Set
Patrol branch:
no target/search decorator, or AIState == Patrol
If all decorators on a branch pass, the branch can run. If one required decorator fails, the selector skips that branch and tries the next one.
Blackboard decorators¶
The Blackboard decorator is the beginner workhorse. It asks a narrow question about a Blackboard key:
TargetActor Is Set?
HasLineOfSight == true?
PatrolLocation Is Set?
AIState == Search?
Good decorator questions are facts, not actions:
- "Do I have a target?"
- "Am I in attack range?"
- "Is search location set?"
- "Is cooldown clear?"
Poor decorator questions:
- "Should I run a complicated trace, set variables, and play effects?"
- "Should I spawn my weapon actor?"
- "Should I directly change movement speed?"
If the condition is expensive or needs setup, put the update in a service or controller event, write the result to the Blackboard, and let the decorator read the key.
Services¶
Services attach to a composite or task and run while that part of the tree is active. They are the common place for "keep this Blackboard fact fresh."
Example chase service:
BTS_UpdateCombatFacts
Interval = 0.2
Random Deviation = 0.05
Event Receive Tick AI
-> Get Blackboard TargetActor
-> Is Valid
true:
Distance = Vector Distance controlled pawn location to target location
Set Blackboard InAttackRange = Distance <= AttackRange
Set Blackboard LastKnownLocation = target location
false:
Set InAttackRange = false
Attach that service to the chase or combat branch, not to the whole tree, if only combat needs those facts.
Good service jobs:
- update
DistanceToTarget; - update
InAttackRange; - keep
LastKnownLocationcurrent while target is sensed; - select a new patrol/search point when a branch starts;
- set controller focus from a target key.
Poor service jobs:
- running the whole AI decision tree manually;
- calling Move To every service tick;
- doing expensive world searches with a tiny interval;
- spawning or destroying gameplay actors repeatedly;
- changing widget/UI state.
Services do not call Finish Execute because they are not tasks. Their job is
to keep facts current while the tree continues to run tasks.
Service timing¶
Services have an Interval and optional Random Deviation.
Use intervals deliberately:
| Fact | Reasonable first interval |
|---|---|
| Distance to current target | 0.1 to 0.25 seconds |
| In attack range | 0.1 to 0.25 seconds |
| Slow patrol point refresh | on activation, or 1.0 second plus |
| Expensive line-of-sight trace | event/perception first, or a modest interval |
The exact number is design-dependent. The principle is stable: do not update a fact 60 times per second unless it really needs frame-level precision.
If a service has Call Tick on Search Start, it can update immediately when
the tree search enters that node, instead of waiting for the first interval.
That is useful for keys like InAttackRange that should be valid before a
decorator makes the next decision.
Observer aborts¶
Observer aborts decide what happens when a decorator's observed condition changes.
The common modes:
| Observer Aborts | Beginner meaning |
|---|---|
| None | Do not interrupt running branches when this condition changes. |
| Self | If this branch is running and its condition becomes false, stop this branch. |
| Lower Priority | If this condition becomes true, stop lower-priority branches to the right so this branch can be considered. |
| Both | Do both: stop this branch when it becomes invalid, and stop lower-priority branches when this branch becomes valid. |
Think of the selector order:
Selector
-> Chase branch Decorator: TargetActor Is Set, Observer Aborts = Both
-> Patrol branch
If the AI is patrolling and TargetActor becomes set, Lower Priority behavior
is what interrupts patrol so chase can start quickly. If the AI is chasing and
TargetActor is cleared, Self behavior is what stops chase so the selector
can fall through to search or patrol.
That is why Both is a common beginner setting on a high-priority chase
decorator.
Why transitions feel stuck¶
When an AI sees the player but keeps patrolling, ask:
Is the chase branch left of patrol?
Does the chase decorator observe the key that changed?
Is Observer Aborts set to Lower Priority or Both?
Did perception set the exact Blackboard key the decorator reads?
Without a lower-priority abort, patrol may finish its current Move To or Wait before the selector considers chase. That can feel like the AI ignored the player.
When an AI loses the player but keeps chasing forever, ask:
Is TargetActor or HasLineOfSight ever cleared?
Does the chase branch have a decorator that becomes false?
Is Observer Aborts set to Self or Both?
Is the Move To task tracking a stale target actor?
Without a self abort, an active chase branch can keep running until its current task returns. If the target key never clears, the branch is still valid.
Abort side effects¶
An abort is not a magic cleanup function for all gameplay state. It stops the running Behavior Tree branch/task. Your own task and pawn logic still need clear boundaries.
Examples:
- a Move To task can be aborted, but the AI may still need a later branch to request a new move or stop movement;
- a custom attack task should handle abort if it opens a damage window or starts a montage;
- a service that set
InAttackRangeshould keep that key honest when the target becomes invalid; - a timer started by a custom task should be cleared by that task or by pawn state, not assumed away.
If a custom Blueprint task implements abort behavior, use the AI-specific abort event for AI agents and finish/cleanup consistently.
When it fails (and what failure does)¶
| Symptom | Likely cause |
|---|---|
| Move To task fails immediately | Blackboard key is unset/wrong type, no controlled pawn, no NavMesh, unreachable goal, or pawn cannot move. |
| Move To never catches a moving player | Track Moving Goal or Observe Blackboard Value is off, or the target key is stale. |
| Patrol ignores newly seen player | Chase branch is lower priority, decorator is not observing the changed key, or observer aborts do not affect lower priority branches. |
| Chase never stops after losing sight | Target/line-of-sight key is never cleared, or the chase decorator does not self-abort. |
| Attack branch flickers | Range key is updated with noisy thresholds, or aborts constantly switch between attack and chase with no hysteresis/cooldown. |
| Service updates do nothing | Service is attached to a branch that is not active, interval has not elapsed, or it sets the wrong Blackboard key. |
| Custom task freezes the tree | It never calls Finish Execute, or abort cleanup leaves latent work running. |
| Branch order seems backward | Selector priority is left-to-right/top-to-bottom; the fallback branch is placed before the urgent branch. |
Failure is usually visible as a branch that does not become active, a task that never finishes, or a Blackboard key that does not contain the value the decorator/task expects.
What these nodes do not do¶
- Move To does not create a controller, pawn, NavMesh, or target key.
- Decorators do not set the facts they test.
- Services do not choose branches by themselves; they update data the tree reads.
- Observer aborts do not invent a better branch; they only force the tree to reconsider according to your layout.
- Aborting a branch does not clean up every custom timer, montage, spawned actor, or pawn variable you started elsewhere.
- Behavior Tree movement does not replace animation, combat, damage, or replication rules.
Lookalikes - which one do I want?¶
| Tool | Use when | Watch out |
|---|---|---|
| Move To task | A Behavior Tree branch should move to a Blackboard actor/vector key. | Still needs NavMesh, controlled pawn, and valid key. |
| AI Move To node | A normal Blueprint event should request one AI move. | Outside the tree; repeated calls can fight BT movement. |
| Move Directly Toward task | You intentionally want straight-line movement without normal nav pathing. | Not a NavMesh pathfinding replacement. |
| Blackboard decorator | A branch should be allowed only when a key condition is true. | It tests facts; it should not perform the action. |
| Service | A branch needs facts refreshed while active. | Use an interval; do not hide the whole AI inside it. |
| Observer Aborts: Self | A running branch should stop when its own condition becomes false. | Does not interrupt lower-priority branches. |
| Observer Aborts: Lower Priority | A newly valid higher-priority branch should interrupt branches to the right. | Does not stop this branch when it becomes invalid. |
| Observer Aborts: Both | A high-priority branch should both preempt fallback behavior and stop itself when invalid. | Can flicker if the watched condition changes too often. |
Rule of thumb: decorators make branches eligible, services update the keys decorators read, Move To performs movement, and observer aborts decide when the tree is allowed to interrupt itself.
Going deeper¶
- Behavior Trees and Blackboards for Blueprint Beginners - the tree/blackboard/controller/pawn split.
- Run Behavior Tree, AIController Setup, and Blackboard Keys - starting the tree and setting keys from perception.
- Simple Patrol, Chase, Attack, and AI Debugging - a complete beginner enemy loop using these pieces.
- AI Move To & the NavMesh - movement and NavMesh failure modes.
- Seeing the player: Pawn Sensing & AI Perception - sensing events that update Blackboard keys.
- Set Timer by Event / Clear Timer by Handle - forget timers and delayed search cleanup.
- The frame: Tick, timers, and timelines - why services and timers are not background threads.
- Official docs: Behavior Tree Node Reference, Behavior Tree Tasks, Behavior Tree Decorators, and Behavior Tree Services.
- Engine source (requires engine access - we do not reproduce it here):
Move To task behavior in
UBTTask_MoveTounderEngine/Source/Runtime/AIModule/Private/BehaviorTree/Tasks/BTTask_MoveTo.cpp; decorator observer behavior throughUBTDecoratorand Blackboard decorators underEngine/Source/Runtime/AIModule/Private/BehaviorTree/Decorators/; service ticking throughUBTServiceclasses underEngine/Source/Runtime/AIModule/Private/BehaviorTree/Services/; tree search, execution, and abort handling inEngine/Source/Runtime/AIModule/Private/BehaviorTree/BehaviorTreeComponent.cpp.