How do you implement patrol behavior for an AI in Unreal Engine?
An AI bot must patrol an ordered list of patrol-point actors in a loop: walk to a point, pause, then advance to the next and repeat indefinitely. Drive this with a Behavior Tree, not with hand-written Tick logic.
Requirements:
location into a Blackboard key; MoveTo then walks there over the NavMesh.
- The next-point selection lives in a custom BT
Taskthat writes the chosen - The index must wrap around so the patrol loops forever.
- Return
Failedwhen there are no patrol points so the tree can react.
Complete the ExecuteTask of the custom task that advances to the next point and publishes it to the PatrolLocation Blackboard key:
EBTNodeResult::Type UBTTask_NextPatrolPoint::ExecuteTask(
UBehaviorTreeComponent& OwnerComp, uint8* NodeMemory)
{
// your code here: advance the wrap-around index on the patrol pawn and
// write the next point's location into the "PatrolLocation" key
}
Write the implementation.
Place patrol-point actors, expose them on the pawn, and use a Behavior Tree Sequence: a custom Task picks the next point into a Blackboard Vector/Object key, MoveTo walks there, then Wait pauses before the index advances and loops.
- ✗Assuming a Behavior Tree cannot loop — a
Sequenceunder a looping parent does - ✗Putting waypoint coordinates in the tree instead of a Blackboard key
- ✗Forgetting a
Waittask, so the AI snaps between points with no pause
- →How would you switch from patrol to chase when perception sees the player?
- →Should patrol points loop, ping-pong, or be chosen randomly — and how?
Idea
Patrol is a loop: pick a point → walk there → wait → next point. A Behavior Tree loops on its own if you put the Sequence under a composite that restarts its children (the tree root does this by default).
Step 1. Custom task — pick the next point
EBTNodeResult::Type UBTTask_NextPatrolPoint::ExecuteTask(
UBehaviorTreeComponent& OwnerComp, uint8* NodeMemory)
{
auto* AICon = OwnerComp.GetAIOwner();
auto* Bot = Cast<APatrolBot>(AICon->GetPawn());
if (!Bot || Bot->PatrolPoints.Num() == 0)
return EBTNodeResult::Failed;
// wrap-around index
Bot->PatrolIndex = (Bot->PatrolIndex + 1) % Bot->PatrolPoints.Num();
AActor* Next = Bot->PatrolPoints[Bot->PatrolIndex];
OwnerComp.GetBlackboardComponent()
->SetValueAsVector(TEXT("PatrolLocation"), Next->GetActorLocation());
return EBTNodeResult::Succeeded;
}
Step 2. Behavior Tree
Sequence (restarted by the root → endless loop)
├─ Task: BTTask_NextPatrolPoint → writes the PatrolLocation key
├─ Task: MoveTo (Blackboard Key = PatrolLocation)
└─ Task: Wait (3 s — pause at the point)
MoveTo paths over the NavMesh. After Wait, the Sequence finishes with success, the root restarts it — the index advances and the bot heads to the next point.