StateTree Integration
Documentation Unreal Engine AI StateTree
Guide to StateTree tasks, structure, and integration with the combat system.
Available StateTree Tasks
| Task | Purpose | When to Use |
|---|---|---|
STTask_BuildDecisionContext | Gathers combat data | Every tick in root state |
STTask_AIMovement | Evaluates and applies movement | Every tick in root state |
STTask_PollAction | Scores and selects action | On entering decision state |
STTask_DoAction | Triggers execution of chosen action | On entering execute state |
STTask_UpdateActionSet | Swaps ActionSet | When changing AI behavior |
STTask_PollCombatRole | Polls current combat role | Every tick, outputs role tag |
STTask_PollFocusActor | Polls controller focus actor | Every tick, outputs target reference |
STTask_SyncActionSet | Syncs ActionSet from pawn's SECActionSetComponent | On entering role state |
STTask_SyncMovementProfile | Syncs MovementProfile for current role | On entering role state |
STTask_PollLastKnownLocation | Outputs a target's last-known location | Investigate / search states (move to where it was last seen) |
All StateTree tasks work with anyAAIControllerthat has aSECCombatControllerComponent. They use the component's static resolution helpers to find AIConfig and combat role data.
Available StateTree Conditions
| Condition | Purpose | When to Use |
|---|---|---|
STCondition_ASCHasTag | Checks the pawn's ASC for gameplay tags | Gate states by ability/status tags |
STCondition_AwarenessState (Awareness State At Least) | Passes when a target's awareness state is ≥ a minimum | Branch Patrol / Investigate / Combat / Search on what the AI has perceived |
Typical StateTree Structure
Root (Always Active)
├─ BuildDecisionContext [Tick]
├─ AIMovement [Tick]
│
├─ Idle State
│ └─ Transition → Combat (when target acquired)
│
└─ Combat State
├─ Decision State
│ ├─ PollAction [Enter]
│ └─ Transition → Execute (when action chosen)
│
└─ Execute State
├─ DoAction [Enter]
└─ Transition → Decision (when complete)
Task Details
STTask_BuildDecisionContext
Inputs:
- AIController (Object)
- DefaultAggressionLevel
- WindowIdIntervalSeconds
Attribute Inputs (Optional):
- HealthAttribute (FGameplayAttribute)
- MaxHealthAttribute (FGameplayAttribute)
- StaminaAttribute (FGameplayAttribute)
- MaxStaminaAttribute (FGameplayAttribute)
Point these at your GAS AttributeSet properties (e.g.
UMyAttributeSet::GetHealthAttribute()). When set, the task reads live values from the pawn's ASC every tick. When left empty, it falls back to BasicHealthComponent (if present) or safe defaults (health percentage 1.0, max health 100).Line of Sight (Optional):
LineOfSightTraceChannel(Collision Channel) - the channel for the LOS trace. Defaults toVisibility; point it at a dedicated channel if your project has one.bLineOfSightTraceComplex(bool) - trace against complex (per-poly) collision. Off uses simple collision, which is faster.
The task traces from the AI's view point to the target's view point each tick and writes the result to
FDecisionContext::bHasLOS. Actions flagged Require Line Of Sight use it as a hard gate.Outputs:
- OutDecisionContext (FDecisionContext struct)
What it does:
- Calculates distance and angle to target
- Reads health and stamina from GAS attributes (or
BasicHealthComponentfallback) - Evaluates health percentages
- Gathers tags from the AI's ASC (
SelfTags), the target's ASC (TargetTags), andUSECWorldTagSubsystem(WorldTags) - Traces line of sight from the AI's eyes to the target and writes
bHasLOS
STTask_PollAction
Inputs:
- AIController
- Context (FDecisionContext)
- EvaluationCooldown
- DebugLog
Outputs:
- ChosenAction (FChosenAction)
What it does:
- Scores all actions in ActionSet
- Applies evaluators
- Checks cooldowns
- Selects best valid action
STTask_DoAction
Inputs:
- Actor
- AIController
- InChosenAction (FChosenAction)
- DebugLog
What it does:
- If Ability: Activates via ASC
- If BT: Runs behavior tree sequence
- Waits for SEC.Action.End event
- Completes when action finishes
Awareness Nodes
These two nodes let the brain branch on what the AI has perceived (via the Awareness System), so you can build patrol → investigate → combat → search loops without wiring delegates by hand.
STCondition_AwarenessState — "Awareness State At Least"
Inputs:
- AIController (Object, Context)
Target(Actor) - the target to test. Leave empty to test the AI's most-aware target.MinState(ESECAwarenessState) - passes when the target's state is ≥ this. DefaultDetected.bInvertResult(bool)
What it does:
- Reads
GetAwarenessState(Target)from the controller's awareness component and compares it toMinState(ordering: Unknown < Forgotten < Suspicious < Lost < Detected). - Gate a Combat state with
MinState = Detected, an Investigate state withMinState = Suspicious, and so on.
STTask_PollLastKnownLocation
Inputs:
- AIController (Object, Context)
Target(Actor) - the target to read. Leave empty to use the AI's most-aware target.
Outputs:
LastKnownLocation(FVector) - bind this straight into an AI Move To destinationAgeSeconds(float) - how stale the location isbValid(bool) - false if there is no recorded locationResolvedTarget(Actor) - the target actually read (handy with the most-aware fallback)
What it does:
- Each tick, reads
GetLastKnownLocationfor the target and exposes it as bindable outputs - the core of "search where I last saw you" behavior.