Movement System
Documentation Unreal Engine AI Movement
Give an enemy tactical positioning: create a movement profile, set the range it holds, point the AI Config at it.
An enemy that circles you, holds its range, backs off when crowded, and paths around corners. You author it as one data asset.
Set it up
30 seconds- 1
Create a Movement Behavior Profile
Right-click in the Content Browser, SEC, Movement Behavior Profile.Content Browser▸ ContentRight-click in the Content Browser, SEC, Movement Behavior Profile. - 2
Set the range it holds
Double-click the asset. Set Desired Distance to the range this enemy fights at, in centimetres. That one number is the whole first pass.DA_Move_Attacker▾DistanceDesired Distance400.0Distance Tolerance0.2Crowd Tolerance0.45Desired Distance is the range. The two tolerances widen the band around it. - 3
Point the AI Config at it
Open the enemy's Enemy AI Config, and under Movement Profiles set Default Movement Profile to the asset. Leave Manage Movement Profiles Automatically ticked.EnemyConfig_Grunt▾Movement ProfilesManage Movement Profiles AutomaticallyDefault Movement ProfileNone▾Default Movement Profile covers every role, so one entry is enough to start. - 4
Play, and watch it work
Press Play and runSEC.Debug.Movement 1in the console. Each enemy gets a line above its head showing its movement layer, whether it is strafing and which way, and its heading.
An enemy only moves once it has something to fight. Movement reads the controller's focus actor, and nothing sets that until a combat target is registered. If the enemy stands still with everything above filled in, that is what is missing. See Getting Started and Targeting.
Tune the range
An enemy holds a band around Desired Distance rather than one exact range, and the band is wider on the crowded side than the far side.
Distance Comfort Zone
MovementBehaviorProfile
Settles hereEases back into placeToo close or too farThe enemy
Comfort band = 2.2m to 4.8m, around a desired 4.0m with Crowd Tolerance 45% on the near side and Distance Tolerance 20% on the far side. Same rings, bands and colors the Movement Behavior Profile editor draws for these three fields, spaced out a little further here so the labels stay readable at this size.
| Field | Default | What to do with it |
|---|---|---|
| Desired Distance | 400 cm | The range this enemy fights at. 250 for a brawler, 600 for something that hangs back. |
| Distance Tolerance | 0.2 | The far half of the band, as a share of Desired Distance. Raise it and the enemy stops closing sooner. |
| Crowd Tolerance | 0.45 | The near half. Raise it for an enemy that stands its ground when you walk into it, lower it for one that insists on its space. |
Inside the band the enemy circles. Closer than the near edge it gives ground. Past the far edge it closes in. Set the two tolerances equal for a band the same width on both sides.
Keep Desired Distance under 800 cm. Above that the enemy sits permanently in the pathfinding layer, where it walks toward the target and never circles.
Watch a live enemy while you tune
The profile editor has a Watching picker. Start Play In Editor, pick a running enemy, and the diagram draws that enemy's real distance and heading against the band you are editing. Change a value and the enemy answers on the next tick.
The rest of the profile
Distance
Desired Distance
400
Distance Tolerance
0.2
Crowd Tolerance
0.5
Rest Behavior
Enable Strafe Rest
Strafe Rest Time Limit
10
Strafe Rest Duration
1.5
Threat Response
Swap Strafe On High Threat
Adjust Distance By Threat
Threat Distance Scale
1
Strafe
Enable Strafing
Strafe Preference Weight
1
Auto Strafe Swap
Strafe Swap Threshold
3
Strafe Swap Cooldown
2
Strafe Time Limits
Enable Strafe Time Limit
Strafe Time Limit
5
Strafe Time Limit Fluctuation
2.5
Rest After Strafe Swap
Strafe Swap Rest Time
0.5
Strafe Swap Rest Fluctuation
0.25
Positioning Rules
Positioning Rules
0 Array elements
Rest Behavior stops an enemy circling forever: after Strafe Rest Time Limit seconds of continuous strafing it pauses for Strafe Rest Duration. Both are jittered per enemy so a pack does not rest in lockstep.
Threat Response needs a Threat Detection component on the controller. Without one, both switches sit inert.
Untick Enable Strafing and this role stops circling entirely: the enemy still approaches, retreats, and steps around other enemies, every other Strafe and Strafe Time Limits field goes inert, and the side it was circling on is remembered for whenever strafing comes back on. With it ticked, Strafe Preference Weight balances circling against closing or opening distance: 1.0 is balanced, below 1.0 favors approach and retreat, above 1.0 favors circling. Tick Auto Strafe Swap and the enemy switches sides on its own once the far side scores enough better, by the ratio in Strafe Swap Threshold, no sooner than Strafe Swap Cooldown allows.
Strafe Time Limits forces a side swap after too long on one side, separately from any score-driven swap. With Enable Strafe Time Limit ticked, a swap fires after roughly Strafe Time Limit seconds, varied by Strafe Time Limit Fluctuation so a pack does not swap in lockstep. Tick Rest After Strafe Swap to pause briefly right after one of these forced swaps, for Strafe Swap Rest Time seconds, varied by Strafe Swap Rest Fluctuation.
Positioning Rules shape where the enemy wants to stand. Add an Angle Preference Rule and set Preferred Angle to 0 for frontal, 90 for flanking, 180 for behind the target. Tick Avoid Instead to invert it. Rules stack, each with its own Weight.
A profile carries the fields above and nothing else. Sample count, avoidance, navmesh sampling, strafe speed, detour, and stuck detection all live on the Movement Evaluator component, so they are the same for every role on that controller.
One profile per combat role
Add entries to Role Movement Profiles to give each combat role its own profile: an aggressive one for Attacker, a patient one for Waiter. Any role you do not list falls back to Default Movement Profile, and the swap happens on its own when the role changes.
Leave no entry with an empty Movement Profile. An entry that names a role but no asset applies nothing, so the enemy keeps whatever the previous role gave it.
Tune the component
Everything that is the same for every role sits on the Movement Evaluator component, on the AI controller.
Movement Evaluator
Apply Movement Input
Num Samples
16
Distance Tolerance
0.2
Crowd Tolerance
0.5
Direction Smoothness
8
Direction Change Penalty
1
Speed Dead Zone
0.1
Target Position Smoothness
5
Use Pivot Smoothing
Strafe
Auto Strafe Swap
Strafe Swap Threshold
3
Strafe Swap Cooldown
2
Strafe Speed Penalty
0.8
Strafe Free Angle
15
Strafe Full Penalty Angle
40
Strafe Preference Weight
1
Retreat
Close Range Retreat Bias
0.5
Retreat Speed Scale
0.5
Yield Retreat To Closing Target
Retreat Yield Strength
1
Strafe Time Limits
Enable Strafe Time Limit
Strafe Time Limit
5
Strafe Time Limit Fluctuation
2.5
Rest After Strafe Swap
Strafe Swap Rest Time
0.5
Strafe Swap Rest Fluctuation
0.3
Strafe Rest
Enable Strafe Rest
Strafe Rest Time Limit
10
Strafe Rest Time Limit Fluctuation
4
Strafe Rest Duration
1.5
Strafe Rest Duration Fluctuation
0.5
Avoidance
Enable Avoidance
Avoidance Radius
100
Avoidance Weight
0.4
Avoidance Slip Bonus
0.8
Velocity Aware Avoidance
Momentum Bias
0.7
Nav Sampling
Enable Nav Aware Sampling
Nav Probe Distance
120
Nav Score Weight
1
Nav Blocked Floor
0.1
Guard Ledge Drops
Nav Edge Speed Floor
0.1
Stuck Detection
Enable Stuck Detection
Stuck Velocity Threshold
50
Stuck Time Threshold
0.5
Stuck Check Interval
0.2
Direction Blending
Direction Blend Count
3
Direction Blend Min Score Ratio
0.7
Hybrid Movement
Enable Hybrid Movement
Hybrid Switch Distance
800
Hybrid Switch Hysteresis
100
Detour
Enable Detour Escalation
Detour Enter Ratio
1.6
Detour Min Excess
200
Detour Recheck Interval
0.5
Detour Use Line Of Sight Pre Gate
Detour Line Of Sight Channel
Visibility
Detour Escalate On Stall
Detour Stall Speed
60
Detour Release Ratio
1.4
Detour Release Min Excess
100
Detour Facing Mode
Use Default Facing
Detour Turn Rate
0
Strategic Facing Mode
Use Default Facing
Strategic Turn Rate
0
Debug it
SEC.Debug.Movement 1 // Layer, strafe side and heading above each enemy
SEC.Debug.Movement.DrawScoring 1 // The 16 sampled directions, red low to green high
SEC.Debug.Movement.DrawAvoidance 1 // Avoidance radii and the pawns being avoided
SEC.Debug.Movement.DrawNav 1 // Navmesh validity and the ledge guard
SEC.Debug.Movement.LogMovement 1 // Layer switches, suspends, pathfinding, stuck, detour
SEC.Debug.All 1 turns every overlay on at once, and SEC.Debug.WatchPawn <name> narrows them to one enemy.Five more log switches exist for narrower work:
LogTick, LogScoring, LogAvoidance, LogStrafeSwap, and LogStrafeState. LogTick fires every tick for every enemy and buries the rest, so turn it on last.AdvancedDebug one enemy from the Details panel
Every console switch above has a matching checkbox on that enemy's Movement Evaluator component, under Movement Evaluator > Debug > Draw and Movement Evaluator > Debug > Log. Ticking one there affects that enemy alone. They are readable and writable from Blueprint, so a debug menu can drive them at runtime.
The per-tick stream writes to its own log category, so you can mute it while one enemy floods the console:
Log LogMovementEvaluatorTick off
AdvancedIt moves, but it never circles
Four causes, in the order worth checking:
- Desired Distance is 800 or higher. Circling only exists in the tactical layer, and 800 cm is where the component hands over to pathfinding.
- It is resting. Strafe rest is on by default: roughly 10 seconds of circling, then a pause of about 1.5 seconds.
- It is crowded. Being pushed inside the near edge of the band favours giving ground over circling, scaled by Close Range Retreat Bias on the component.
- It is still travelling. While the distance error is large the enemy runs in or backs off, and circling only takes over once it reaches the band.
An enemy that stands still inside the band is doing that on purpose. With no neighbours to avoid, no positioning rules, and nothing to gain from moving, it holds its spot.
AdvancedIt does not move at all
- No focus actor. Nothing registered a combat target, so there is nothing to move relative to. This is the common one and it logs nothing.
- The Movement Evaluator is on the pawn. It belongs on the AI controller. On a pawn it warns once at BeginPlay and then does nothing.
- A plain AAIController. It needs a SEC Combat Controller component to resolve the config at possession, and a SEC Brain component to tick movement.
AEnemyControllerBaseships with both. - No navmesh. Past 800 cm the enemy asks for a path, the request fails every tick, and it never closes the gap.
- A leftover
SEC.State.IsMovementBlockedtag on the pawn's ability system component freezes it outright. - Apply Movement Input is off on the component, which is evaluate-only mode.
How it steers
AdvancedDirection sampling
Each tick the component samples Num Samples directions (16 by default) around the enemy and scores each one.
Viewport
LVL_SEC_Showcase
AI Pawn
Target
Ideal Range
Green arrows = High Score (Preferred Direction)
A direction's score comes from how well it serves the target distance, whether it faces the target, whether another enemy sits in the way, whether it stays on walkable navmesh, and any positioning rules on the profile. The best direction wins, and the top few blend for a smooth result.
AdvancedTwo layers, and rounding corners
The component switches strategy by distance. Inside Hybrid Switch Distance (800 cm) it drives the pawn directly, which is what makes strafing responsive. Beyond it, or when a path is blocked, it hands over to navmesh pathfinding.
When a target ducks behind a corner it sits close in a straight line but far along the navmesh, so plain strafing grinds into the wall. Detour escalation notices and hands off to pathfinding to round the corner, then resumes strafing the instant the enemy regains the angle. It is on by default, acts only inside 800 cm, and stays inert with no navmesh.
Detour engages when the walking route runs much longer than the straight line, or when the enemy wants to close on a target it cannot see and is not gaining ground. It releases once the walk straightens out. A target walled off with no route at all leaves the enemy tactical rather than walking it into a dead end.
Tuning lives on the component under Detour. Raise Detour Enter Ratio or Detour Min Excess if minor bumps trigger pathfinding, and raise Detour Stall Speed if a slow corner grind does not register.
SEC.Debug.Movement.LogMovement 1 prints each recheck.AdvancedGiving ground under pressure
An enemy pushed inside its near edge backs away at a fraction of its walk speed, set by Retreat Speed Scale (0.45) on the component.
With Yield Retreat To Closing Target on, an enemy whose target closes faster than it can retreat holds its footing and circles instead, so a player charging at a run does not walk it backward into a wall. The check weighs the target's speed against this enemy's retreat speed, so it needs no per-enemy tuning.
Close Range Retreat Bias (0.5) is how hard crowding favours giving ground over circling. Raise it toward 1 for a harder push out, drop it to 0 to leave the enemy circling at any range.
AdvancedStaying off ledges, and avoiding hazards
Each sampled direction gets a walkability score, so enemies stop strafing off ledges and into walls mid-fight. It is a preference rather than a veto, so a boxed-in enemy still picks its safest direction instead of freezing. On by default, inert with no navmesh.
To make enemies avoid a patch they can still walk on (lava, spikes):
- Create a Blueprint subclass of
NavAreawith a distinct draw color. - Drop a Nav Modifier Volume over the patch, set its Area Class to that area, and rebuild navigation. Press P to check it tints.
- On the Movement Evaluator, add the area to Hazard Area Avoidance with a strength from 0 to 1.
0ignores it,1treats it like a wall,0.75routes around it but crosses when cornered.
Raise the area's Default Cost as well, so long-range pathfinding avoids it too. A patch authored as
NavArea_Null carves a hole in the navmesh, which the enemy treats as a wall with no setup at all.AdvancedWhich way the pawn looks while it travels
By default an enemy keeps looking at its target however it moves, which reads well up close and looks wrong on a long walk or around a blind corner. Each pathfinding layer can face its direction of travel instead, through Strategic Facing Mode and Detour Facing Mode on the component. Strategic Turn Rate and Detour Turn Rate set how fast it turns, in degrees per second, and 0 keeps the controller's own turn speed.
Turning the pawn away from its target changes what every angle-based system sees, because they all read the pawn's real facing: reaction angle gates, action angle scoring, and the awareness sight cone. An enemy rounding cover with Face Movement Direction can lose sight of the player mid-detour, which is usually the point.
AdvancedStrafe animations at full speed
Strafe animations read wrong at a full run, so the pawn slows as its heading turns away from the direction it faces. Strafe Speed Penalty (0.75) sets the cost, Strafe Free Angle (15 degrees) is the band around straight ahead that costs nothing, and Strafe Full Penalty Angle (40 degrees) is where the cost tops out.
Raise Strafe Free Angle if an enemy closing distance looks like it is jogging, since direction scoring angles the approach a few degrees while holding a strafe side. Set it to 0 to charge the penalty at any angle off forward. It applies to the tactical layer only.
AlternativeDriving locomotion with root motion instead
To move the character with root motion rather than movement input, untick Apply Movement Input. The component keeps scoring and publishing a direction every tick without driving the pawn. Feed that direction into your Anim Blueprint, and the locomotion animations move the character.
Read one of these each tick and feed your blendspace:
- Get Current Direction Angle: signed yaw in degrees, 0 ahead, +90 right, -90 left. Good for a 1D turn or strafe blendspace.
- Get Current Direction Local: a 2D vector, X forward and Y right, for a standard 2D locomotion blendspace.
- Get Current Direction: the world-space direction, raw.
In this mode the component stays tactical-only and issues no path moves.
AdvancedReacting when a target hides behind something solid
The detour recheck already works out whether the enemy can see its target and whether a route exists, so a cover-break behaviour can read it off the Movement Evaluator:
| Getter | Answers |
|---|---|
| Is Approach Blocked | Sight blocked and no route: the target is walled off. This is the cover-break trigger. |
| Has Line Of Sight To Target | Clear view at the last recheck. |
| Is Target Reachable | A full navmesh route existed at the last route measurement. Read it through Is Approach Blocked rather than alone. |
| Is Approach Stalled | Tactical steering is grinding cover without gaining ground. |
On Target Line Of Sight Changed fires whenever sight flips, and On Approach Blocked fires once when the target becomes walled off.
The pattern: bind On Target Line Of Sight Changed, start a timer when it reports false, and on expiry check Is Approach Blocked. If it still holds, line-trace from the pawn to the player and the first blocking hit is the obstacle to attack. Clear the timer when sight returns.
AdvancedEvery movement event
| Event | Fires when |
|---|---|
OnStrafeStarted | Strafing begins, carrying the side |
OnStrafeEnded | Strafing stops |
OnStrafeSwapped | Direction changes, carrying the new side |
OnStrafeResting | Strafe fatigue rest begins |
OnMovementSuspended | Movement suspended, carrying the duration |
OnMovementResumed | Suspension ends |
OnArrivedAtDesiredDistance | The enemy reaches its band |
OnDepartedDesiredDistance | The enemy leaves its band |
OnMovementLayerChanged | The layer switches, carrying new and previous |
OnSwitchToPathfinding | Switched to pathfinding |
OnSwitchToDirectInput | Switched to direct steering |
OnPathfindingFailed | Pathfinding blocked or unreachable |
OnAttackApproachComplete | An attack approach reached its distance |
OnAttackApproachFailed | An attack approach failed |
OnTargetLineOfSightChanged | Sight to the target flips |
OnApproachBlocked | The target becomes walled off |
AlternativeMoving a pawn outside the loop
Three Behavior Tree tasks move the pawn without the evaluation loop, for use inside an action's tree:
| Task | Does |
|---|---|
| Move Until Distance | Paths toward the blackboard target until within a set distance. Takes a timeout and a max chase distance. |
| Make Distance | Backs away from a target until it reaches a distance. Includes stuck detection and a timeout. |
| Debug SEC Values | Logs the SEC_ blackboard values to the log and the screen. |