Configuration Reference
Documentation Unreal Engine AI Configuration Reference
Complete reference for all data assets: AICombatConfig, ActionSets, Movement Profiles, and Damage Config.
All data assets in one place. Link here from system pages for specific configuration details.
EnemyAIConfig
Defines combat role selection, behavior logic, and action set binding for an AI.
Config Resolution Order:
SECCombatControllerComponentcached config (fromDefaultAIConfigproperty)- Pawn implementing
IEnemyAIConfigProvider
Set the config on the pawn for per-enemy customization, or on the
SECCombatControllerComponent's DefaultAIConfig when all units sharing a controller should use the same config.SECCombatControllerComponent Properties
| Property | Category | Default | Purpose |
|---|---|---|---|
DefaultAIConfig | AI|SEC | nullptr | Fallback AI Config when pawn doesn't provide one |
bAutoRegisterForCombatRoles | Combat Role | true | Auto-register with the role subsystem on possession |
bEnableThreatDetection | Threat Response | true | Enable ThreatDetectionComponent on BeginPlay |
bDropWeaponOnDeath | AI|SEC|Weapon | true | Auto-drop equipped weapon with physics on death. Set to false to handle weapon drop manually (e.g. via AnimNotify or K2_OnDeath). |
SECCombatControllerComponent Delegates
| Delegate | Purpose |
|---|---|
OnCombatRoleChanged | Broadcast when combat role changes (new role, old role) |
OnCombatTargetLost | Broadcast when assigned combat target is destroyed/unregistered |
OnCombatRoleSystemReady | Broadcast after successful registration with the role subsystem. Safe to call ForceAssignRole here. |
OnDeath | Broadcast at the end of HandleDeath(), after all combat systems are shut down. Safe to enable ragdoll, play death VFX, or destroy the actor here. |
MovementBehaviorProfile Threat Response
These settings live on the
MovementBehaviorProfile data asset, so they automatically change when the AI switches combat roles:| Property | Default | Purpose |
|---|---|---|
bSwapStrafeOnHighThreat | false | Swap strafe direction when threat duration exceeded |
bAdjustDistanceByThreat | false | Adjust movement distance based on threat level |
ThreatDistanceScale | 1.0 | Scale factor: DistMultiplier = 1.0 + ThreatLevel * Scale |
Full Structure
// Role Registration
bool AutoRegisterForCombatRoles; // Auto-register with role subsystem
TArray<FGameplayTag> AllowedRoles; // Roles this AI can take
int32 Priority; // Lower = higher priority for slots
FGameplayTag PreferredRole; // Default role when available
// Fitness Evaluation
TArray<URoleEvaluator*> FitnessEvaluators; // Scoring objects for role assignment
// Target Selection
UTargetSelector* TargetSelector; // Per-AI target selector (instanced)
bool bIgnoreTargetRedistribution; // Opt out of periodic target reshuffling
// Behavior
FSoftObjectPath DefaultStateTree; // Optional StateTree; empty = native C++ combat loop
FSECDecisionContextParams DecisionContextParams; // Tunables for the decision context
// Action Set Management
bool ManageActionSetsAutomatically; // Swap ActionSets based on role
UActionSet* DefaultActionSet; // Fallback ActionSet
TMap<FGameplayTag, FRoleActionSetMapping> RoleActionSets; // Per-role ActionSets
// Reaction Set Management
bool bManageReactionSetsAutomatically; // Swap ReactionSets based on role
UReactionSet* DefaultReactionSet; // Fallback ReactionSet
TMap<FGameplayTag, FRoleReactionSetMapping> RoleReactionSets; // Per-role ReactionSets
// Movement Profile Management
bool ManageMovementProfilesAutomatically; // Swap Movement Profiles based on role
UMovementBehaviorProfile* DefaultMovementProfile; // Fallback Profile
TMap<FGameplayTag, FRoleMovementProfileConfig> RoleMovementProfiles; // Per-role ProfilesExample
Name: DA_SEC_CombatConfig_Default
CombatRole
AutoRegisterForCombatRoles: true
RoleRegistration
AllowedRoles:
- SEC.Role.Attacker
- SEC.Role.Flanker
- SEC.Role.Supporter
- SEC.Role.Waiter
Priority: 0
PreferredRole: SEC.Role.Attacker
FitnessEvaluators
- DistanceEvaluator
- BP_HealthEvaluator
- BP_RandomEvaluator
Behavior
DefaultStateTree: StateTree_SEC_Core // optional; leave empty to run the native C++ combat loop
ActionSets
ManageActionSetsAutomatically: true
DefaultActionSet: DA_SEC_ActionSet_Attacker
RoleActionSets
SEC.Role.Waiter → DA_SEC_ActionSet_Waiter
SEC.Role.Flanker → DA_SEC_ActionSet_Flanker
SEC.Role.Supporter → DA_SEC_ActionSet_Ranged
ReactionSets
bManageReactionSetsAutomatically: true
DefaultReactionSet: DA_SEC_ReactionSet_Default
RoleReactionSets
SEC.Role.Attacker → DA_SEC_ReactionSet_Aggressive
SEC.Role.Waiter → DA_SEC_ReactionSet_Defensive
MovementProfiles
ManageMovementProfilesAutomatically: true
DefaultMovementProfile: DA_SEC_Movement_Aggressive
RoleMovementProfiles
SEC.Role.Waiter → DA_SEC_Movement_Passive
SEC.Role.Flanker → DA_SEC_Movement_FlankingFitness Evaluators are editor-instanced UObjects. Inherit fromURoleEvaluatorto create custom scoring logic for role assignment.
Decision Context Params
DecisionContextParams (a FSECDecisionContextParams, under Behavior) tunes how the decision context is built each tick. STTask_BuildDecisionContext resolves these from the config on EnterState, so they travel with the config rather than living on the StateTree node.| Property (editor label) | Default | Purpose |
|---|---|---|
AggressionLevel | 1.0 | Baseline aggression written into the decision context. 0 = defensive, 1 = balanced, 2 = aggressive. Clamped 0-2. |
WindowIdIntervalSeconds | 1.0 | Seconds between window increments that reseed score variation. 0 = never advance. |
LineOfSightTraceChannel ("LOS Trace Channel") | Visibility | Collision channel for the line-of-sight trace. Point it at a dedicated visibility channel if the project has one. |
bLineOfSightTraceComplex ("LOS Trace Complex") | false | Trace against complex (per-poly) collision. Off uses simple collision (faster). |
Decision-context health comes fromUBasicHealthComponent(else 1.0) and Stamina is fixed at 100.FSECDecisionContextParamsholds no GAS attribute fields. For attribute-backed health or stamina scoring, use an Attribute Scorer or Attribute Gate on the action instead.
Recovery
Recovery group on UEnemyAIConfig. After an enemy commits an action, these suspend its offensive action selection while movement and reactions keep running. Every field defaults to 0, so recovery is off and existing configs are unchanged until you set one. See Recovery Time for the full behavior.// Recovery
float ActionRecoveryTime; // Seconds suspended after an action completes or times out (0 = off)
float InterruptRecoveryTime; // Seconds suspended after an interrupt or cancel; keep below ActionRecoveryTime
float ActionRecoveryTimeRandomization; // ± jitter on completion recovery, so a pack does not act in lockstep
TObjectPtr<USECActionHook> GlobalHook; // Optional instanced lifecycle hook run for every action this enemy commitsA single action can replace the global window. On itsFActionSpecRecovery group, setbOverrideRecoveryTimeandRecoveryTime(absolute, not additive). Completion uses the override if set; interrupt or cancel always usesInterruptRecoveryTime; a timeout always uses the globalActionRecoveryTime.
ActionSet
Used by: Action System
Contains an array of
FActionSpec, which are all available actions for an AI.Creating an ActionSet
- Right-click → Miscellaneous → Data Asset → ActionSet
- Add actions to the Actions array
- Configure each action's properties
FActionSpec Structure
struct FActionSpec
{
// Identity
FName ActionId; // Unique identifier within the set
// Execution: instanced method that owns how the action runs
TObjectPtr<USECExecutionMethod> ExecutionMethod; // Gameplay Ability, Behavior Tree Sequence, or your own subclass
// Scoring
float SelectionWeight; // Base priority multiplier
float RiskPenalty; // Divides the final score (1.0 = no penalty)
TMap<FGameplayTag, float> TagScoreMultipliers; // Situational tag multipliers
FSECCustomScoring CustomScoring; // Scoring list: Scorers (multiply) + Gates (veto)
// Cooldowns
FActionCooldown Cooldown;
float Duration; // Time before reuse
float InitialCooldown; // Cooldown applied on spawn
float RandomizationPercent; // Cooldown randomness (±%)
// Chaining
FName PreferredNextActionId; // Bonus for this action next
float ChainBonusMultiplier; // Score multiplier if chaining
// Preconditions (Hard Gates)
FGameplayTagContainer RequiresTags;// Must have these to use
FGameplayTagContainer BlockTags; // Cannot use if these exist
bool bRequireLineOfSight; // Only fire with a clear LOS to target
FGameplayTagContainer AddTags; // Added while action active
};Distance, angle, health, speed, and stamina are not fields onFActionSpec. They are opt-in entries in theCustomScoringlist. Add a built-in Distance Scorer, Angle Scorer, Health Scorer, Speed Scorer, or Stamina Gate to score or gate on those dimensions. See Built-in Scorers & Gates below. An action with no Distance Scorer is distance-agnostic.
FRangeEval Explained
The sweet-spot curve used as the
Range on the Distance, Angle, Health, and Speed Scorers, and as the ValueEval on the Attribute Scorer:struct FRangeEval
{
float MinValue; // Score = 0 below this (invalid)
float OptimalMin; // Score = 1.0 starts here
float OptimalMax; // Score = 1.0 ends here
float MaxValue; // Score = 0 above this (invalid)
};Visualization:
0 100 250 400
|-----|========|--------|
0.0 1.0 1.0 0.0
↑ ↑ ↑ ↑
Min OptMin OptMax Max
Example: A Distance Scorer valid 0-400cm, optimal 100-250cm:
Range.MinValue = 0;
Range.OptimalMin = 100;
Range.OptimalMax = 250;
Range.MaxValue = 400;Built-in Scorers & Gates
Distance, angle, health, speed, and stamina are opt-in. Add an entry to an action's Scoring list (
CustomScoring), pick one of the built-in classes, and tune its single property. Omit the entry and that dimension does not influence the score. Scorers fold a multiplier into the score (1.0 = no effect); Gates veto the action when they fail. For deeper coverage and the GetDisplayName() labeling hook, see Scorers & Gates.| Class (editor name) | Property | Default | Reads | Notes |
|---|---|---|---|---|
| Distance Scorer | Range (FRangeEval) | MakeMeleeRange() | AI-to-target distance (cm), 0 with no target | Range OptimalMin/Max also feed the positioning query (GetIdealDistanceForAction) |
| Angle Scorer | Range (FRangeEval) | MakeFrontalAngle() | Absolute angle to target (deg), 0 facing it, 0 with no target | |
| Health Scorer | Range (FRangeEval) | MakeAlwaysOne() | AI health 0-1 from the decision context (BasicHealthComponent) | For a GAS health attribute use an Attribute Scorer |
| Speed Scorer | Range (FRangeEval) | MakeAlwaysOne() | AI horizontal speed (cm/s) | |
| Stamina Gate | MinStamina | 0 | Decision-context Stamina (100 by default) | Vetoes unless Stamina >= MinStamina; for a GAS stamina attribute use an Attribute Gate |
| Attribute Scorer | Attribute, NormalizeBy, ValueEval (FRangeEval) | n/a | A GameplayAttribute on the owning ASC | Optionally divide by NormalizeBy (e.g. Mana / MaxMana) before scoring |
| Attribute Gate | Attribute, MinValue, MaxValue | 0 / 0 | A GameplayAttribute on the owning ASC | Pass when the attribute is in [MinValue, MaxValue]; MaxValue <= 0 disables the upper bound |
The decision context never reads GAS health or stamina attributes. Health comes fromUBasicHealthComponent(else 1.0) and Stamina is fixed at 100. For GameplayAttribute-backed health, stamina, mana, or any other pool, use an Attribute Scorer or Attribute Gate on the action.
Auto-migration: existing ActionSets migrate once on load. Each action's oldDistanceEvalbecomes a Distance Scorer andAngleEvalan Angle Scorer; a non-default Health or Speed range becomes a Health or Speed Scorer; aStaminaCostabove 0 becomes a Stamina Gate. Scoring is unchanged. Re-save the asset to persist. New actions ship with an empty Scoring list (distance-agnostic until you add a Distance Scorer).
MovementBehaviorProfile
Used by: Movement System
The role-swappable data asset. It holds only the fields a combat role changes. The rest of the movement tuning (avoidance, hybrid switching, detour, navmesh sampling, strafe feel) lives on the
MovementEvaluatorComponent itself, the same for every role. See the Movement System for that surface.Full Structure
// Distance
float DesiredDistance; // Ideal distance to hold (cm), default 400
float DistanceTolerance; // Comfort band as a fraction of desired (0.05-0.5), default 0.2
// Strafe Rest (fatigue)
bool bEnableStrafeRest; // Rest after continuous strafing, default true
float StrafeRestTimeLimit; // Seconds of strafing before a rest (3-60), default 10
float StrafeRestDuration; // Rest length in seconds (0.5-10), default 1.5
// Threat Response
bool bSwapStrafeOnHighThreat; // Swap strafe side under high threat, default false
bool bAdjustDistanceByThreat; // Back off as threat rises, default false
float ThreatDistanceScale; // How strongly threat pushes distance out (0-5), default 1.0
// Custom Rules
TArray<UPositioningRule*> PositioningRules; // Instanced direction modifiers, empty by defaultExample Profile
Name: DA_AggressiveMelee
DesiredDistance: 300
DistanceTolerance: 0.15
bEnableStrafeRest: true
StrafeRestTimeLimit: 15.0
StrafeRestDuration: 0.5
bSwapStrafeOnHighThreat: false
bAdjustDistanceByThreat: false
ThreatDistanceScale: 1.0
PositioningRules: []Built-in Presets
FMovementBehaviorConfig factory methods fill the profile-level fields for common archetypes (applied in C++ via ApplyBehaviorConfig):FMovementBehaviorConfig::MakeDefault(); // Balanced (400 cm)
FMovementBehaviorConfig::MakeAttacker(); // Close, aggressive, minimal rest (300 cm)
FMovementBehaviorConfig::MakeWaiter(); // Far, patient, frequent rest (600 cm)
FMovementBehaviorConfig::MakeFlanker(); // Medium, quick repositioning (400 cm)
FMovementBehaviorConfig::MakeSupporter(); // Medium-far, moderate rest (500 cm)
FMovementBehaviorConfig::MakeElite(); // Relentless pressure, very short rest (350 cm)Positioning Rules are instanced UObjects. Inherit fromUPositioningRuleand overrideEvaluateDirection()for custom direction scoring. The built-inUAnglePreferenceRulecovers flanking, backstab, and frontal positioning.
DamageConfig
Used by: Melee Trace System
Contains damage values and type for melee attacks.
Full Structure
float BaseDamage; // Base damage value
TSubclassOf<UDamageType> DamageType; // Damage type class
float ImpulseStrength; // Physics impulse on hit
bool bCanBeBlocked; // Can target block this?
bool bCanBeParried; // Can target parry this?
bool bCanCritical; // Can this crit?
float CriticalMultiplier; // Damage multiplier on crit
float CriticalChance; // Base crit chance (0.0-1.0)Example
Name: DA_SwordDamage
BaseDamage: 25.0
DamageType: UDamageType_Physical
ImpulseStrength: 500.0
bCanBeBlocked: true
bCanBeParried: true
bCanCritical: true
CriticalMultiplier: 2.0
CriticalChance: 0.1Usage
Assigned to weapons via the
DamageConfig property. Applied during melee traces.// In weapon Blueprint:
DamageConfig: DA_SwordDamage