- Updated `CONTEXT.md` to reference the new Manual Implementation Guide and Build Checklist in blueprint spec files. - Added a detailed Manual Implementation Guide to `01_GI_GameTagRegistry.md`, including class setup, variable initialization, function implementations, and a build checklist. - Introduced a Manual Implementation Guide section in `22_BPC_PhysicsDragSystem.md` with step-by-step instructions for setup and function logic. - Expanded `28_BPC_ConsumableSystem.md` with a comprehensive Manual Implementation Guide detailing class setup, variable initialization, function implementations, and networking. - Enhanced `69_BP_WeaponBase.md` with a Manual Implementation Guide covering class setup, variable defaults, function implementations, and networking. - Added a Manual Implementation Guide to `84_AI_BaseAgentController.md`, outlining class setup, variable initialization, function implementations, and networking. - Updated `TEMPLATE.md` to version 2.0, incorporating the Manual Implementation Guide and Build Checklist for human implementers. - Revised `INDEX.md` to reflect the new purpose and content of blueprint specifications, emphasizing the inclusion of the Manual Implementation Guide.
14 KiB
AI_BaseAgentController — AI Controller
Blueprint Spec — UE 5.5–5.7
Parent Class
AIController
Dependencies
BP_EnemyBase— PawnBPC_AIPerceptionSystem— SensingBB_AgentBoard— Decision-makingBPC_AIStateMachine— High-level statesBPC_AlertSystem— Threat awarenessBPC_HealthSystem— Self healthI_Damageable— Damage receptionDA_AIProfile— AI configuration
Purpose
Central brain for enemy AI characters. Manages perception, decision-making via Behavior Trees, high-level state machine transitions, alert level propagation, and combat coordination. Possesses BP_EnemyBase pawns and controls their actions through Blackboard values and Behavior Tree execution.
Variables
| Name | Type | Description |
|---|---|---|
AIProfile |
DA_AIProfile | Configuration asset |
PossessedEnemy |
BP_EnemyBase | Current pawn reference |
BlackboardComp |
UBlackboardComponent | Blackboard instance |
BehaviorTreeComp |
UBehaviorTreeComponent | Behavior tree runner |
PerceptionComp |
BPC_AIPerceptionSystem | Sensory input |
StateMachine |
BPC_AIStateMachine | State logic |
AlertSystem |
BPC_AlertSystem | Threat level |
bIsActive |
Bool | Enabled / disabled |
AggressionRange |
Float | Engage distance |
SuspicionRange |
Float | Investigate distance |
CombatRange |
Float | Preferred combat distance |
HomeLocation |
FVector | Spawn or patrol anchor |
LastKnownPlayerLocation |
FVector | Blackboard updated |
bHasLineOfSight |
Bool | LOS status |
LostPlayerTimer |
Float | Seconds since last sighting |
Blackboard Keys
| Key Name | Type | Description |
|---|---|---|
SelfActor |
Object | Self reference |
TargetActor |
Object | Current threat |
TargetLocation |
Vector | Last known threat location |
HomeLocation |
Vector | Patrol anchor |
AIState |
Enum (EAIState) | Current state |
AlertLevel |
Float | 0.0–1.0 awareness |
bHasLOS |
Bool | Line of sight |
bIsInvestigating |
Bool | Searching location |
PatrolIndex |
Int | Current waypoint |
CombatStance |
Enum | Aggressive / Defensive |
StimulusLocation |
Vector | Sound/sight trigger point |
Enums
| Enum | Values | Description |
|---|---|---|
EAIState |
Idle, Patrol, Suspicious, Alerted, Combat, Searching, Fleeing, Disabled | AI behavior state |
Functions
| Name | Inputs | Outputs | Description |
|---|---|---|---|
OnPossess |
Pawn: APawn | — | Bind blackboard, run BT |
OnUnPossess |
— | — | Cleanup |
InitializeAI |
Profile: DA_AIProfile | — | Set up components |
SetAIState |
NewState: EAIState | — | State machine transition |
UpdatePerception |
Stimulus: FAIStimulus | — | Process sensory input |
SetTarget |
Target: AActor | — | Update blackboard target |
ClearTarget |
— | — | Target lost |
StartInvestigation |
Location: FVector | — | Move to investigate |
RequestReinforcements |
— | — | Alert nearby allies |
GetCombatReadiness |
— | Float | Based on health, ammo, alert |
OnTakeDamage |
DamageResult: FDamageResult | — | React to being hit |
CanSeeTarget |
— | Bool | LOS check |
LostSightOfTarget |
— | — | Start search timer |
ReturnToPatrol |
— | — | Reset to patrol state |
GetHomeLocation |
— | FVector | Patrol anchor |
SetFocalPoint |
Location: FVector | — | Aim facing direction |
Event Dispatchers
| Name | Parameters | Fired When |
|---|---|---|
OnAIStateChanged |
OldState: EAIState, NewState: EAIState | State transition |
OnTargetAcquired |
Target: AActor | New threat detected |
OnTargetLost |
— | Target out of range/perception |
OnAlertRaised |
AlertLevel: Float | Alert threshold crossed |
OnReinforcementRequested |
Location: FVector | Call for backup |
Blueprint Flow
[OnPossess]
└─► PossessedEnemy = Cast<BP_EnemyBase>(Pawn)
└─► AIProfile = PossessedEnemy.AIProfile (or set from spawner)
└─► InitializeAI(AIProfile)
└─► RunBehaviorTree(AIProfile.BehaviorTree)
└─► SetHomeLocation(Pawn.GetActorLocation)
[InitializeAI]
└─► Create BPC_AIPerceptionSystem if not exists
└─► Create BPC_AIStateMachine
└─► Create BPC_AlertSystem
└─► PerceptionComp.Initialize(AIProfile.PerceptionConfig)
└─► StateMachine.Initialize(EAIState.Patrol)
└─► AlertSystem.Initialize()
└─► Set AIState = Patrol in Blackboard
[UpdatePerception — called by PerceptionComp dispatcher]
└─► If Stimulus.Type == Sight && Stimulus.bSuccess:
LastKnownPlayerLocation = Stimulus.StimulusLocation
AlertSystem.RaiseAlert(SightAlertValue)
If AlertSystem.AlertLevel >= AIProfile.CombatThreshold:
SetTarget(Stimulus.Instigator)
SetAIState(Combat)
Else:
SetAIState(Suspicious)
└─► If Stimulus.Type == Hearing && Stimulus.bSuccess:
AlertSystem.RaiseAlert(HearingAlertValue)
StartInvestigation(Stimulus.StimulusLocation)
SetAIState(Searching)
└─► If Stimulus.Type == Damage:
SetTarget(Stimulus.Instigator)
AlertSystem.RaiseAlert(DamageAlertValue)
SetAIState(Combat)
RequestReinforcements()
[OnTakeDamage]
└─► AlertSystem.RaiseAlert(MaxAlertValue)
└─► SetTarget(DamageResult.Instigator)
└─► SetAIState(Combat)
Communications With
| Target | Method | Why |
|---|---|---|
BP_EnemyBase |
Possessed pawn | Movement, animation, abilities |
BPC_AIPerceptionSystem |
Get Component | Sensory stimulus processing |
BB_AgentBoard |
Get Component | Blackboard updates |
BPC_AIStateMachine |
Get Component | State transitions |
BPC_AlertSystem |
Get Component | Threat level queries |
BPC_HealthSystem |
Get on Pawn | Health events |
| Nearby AI Controllers | Direct / Event | Reinforcement calls |
Reuse Notes
- Designed as parent for all enemy types (humanoid, creature, drone)
- Perception, alerts, and state machine are swappable components
- Behavior tree is data-driven via AIProfile
- All decision values (ranges, thresholds, speeds) come from data asset
- Renamed from
BPC_AIControllerBasetoAI_BaseAgentControllerper Master naming convention. - Cross-references updated:
BPC_PerceptionComponent→BPC_AIPerceptionSystem,BPC_BehaviorTreeManager→BB_AgentBoard,BPC_HealthComponent→BPC_HealthSystem.
Manual Implementation Guide
Class Setup
- Create Blueprint Class: Parent =
AIController, Name =AI_BaseAgentController - Save to:
Content/Framework/AI/ - In Class Defaults: set
Auto Possess AI=Placed in World or Spawned
Variables (Add to Class Defaults)
| Variable | Type | Default | Instance Editable |
|---|---|---|---|
AIProfile |
DA_AIProfile |
None | ✓ |
PossessedEnemy |
BP_EnemyBase (Object Ref) |
None | |
BlackboardComp |
Blackboard Component (Object Ref) |
None | |
BehaviorTreeComp |
Behavior Tree Component (Object Ref) |
None | |
PerceptionComp |
BPC_AIPerceptionSystem (Object Ref) |
None | |
StateMachine |
BPC_AIStateMachine (Object Ref) |
None | |
AlertSystem |
BPC_AlertSystem (Object Ref) |
None | |
bIsActive |
Boolean |
true |
✓ |
AggressionRange |
Float |
1500.0 |
✓ |
SuspicionRange |
Float |
3000.0 |
✓ |
CombatRange |
Float |
800.0 |
✓ |
HomeLocation |
Vector |
(0,0,0) |
|
LastKnownPlayerLocation |
Vector |
(0,0,0) |
|
LastKnownPlayerLocation |
Vector |
(0,0,0) |
|
bHasLineOfSight |
Boolean |
false |
|
LostPlayerTimer |
Float |
0.0 |
Function Implementations
Event OnPossess(Pawn: Pawn)
[Event OnPossess]
Step 1: Call Parent OnPossess
Step 2: Cast Pawn to BP_EnemyBase → Set PossessedEnemy
Step 3: Get AIProfile from PossessedEnemy (or a spawner data)
Step 4: Get Blackboard Component → Set BlackboardComp
Step 5: Get Behavior Tree Component → Set BehaviorTreeComp
Step 6: Get Component by Class (BPC_AIPerceptionSystem) → Set PerceptionComp
└─ If not found on Pawn: Create and attach dynamically
Step 7: Get Component by Class (BPC_AIStateMachine) → Set StateMachine
Step 8: Get Component by Class (BPC_AlertSystem) → Set AlertSystem
Step 9: Set HomeLocation = Pawn.GetActorLocation()
Step 10: Set Blackboard value "SelfActor" to Self
Step 11: Set Blackboard value "HomeLocation" to HomeLocation
Step 12: Set Blackboard value "AIState" to EAIState::Patrol
Step 13: Run Behavior Tree (AIProfile.BehaviorTree)
Step 14: PerceptionComp.Initialize(AIProfile.PerceptionConfig)
Step 15: StateMachine.Initialize(EAIState::Patrol)
Step 16: AlertSystem.Initialize()
Nodes: Cast To BP_EnemyBase, Get Blackboard, Set Value as Object/Vector/Enum, Run Behavior Tree, Create Component (if needed), Get Actor Location
Event OnUnPossess(Pawn: Pawn)
[Event OnUnPossess]
Step 1: Stop Behavior Tree
Step 2: Clear Blackboard values (TargetActor = None, AIState = Disabled)
Step 3: PerceptionComp.Deinitialize()
Step 4: Call Parent OnUnPossess
UpdatePerception(Stimulus: AIStimulus) → void
This is called by BPC_AIPerceptionSystem dispatcher when any sense triggers.
[Function: UpdatePerception]
Step 1: Branch on Stimulus.WasSuccessfullySensed()
False → Return (ignore failed perception)
Step 2: Switch on Stimulus.Type:
Case Sight:
Step 2a: Set LastKnownPlayerLocation = Stimulus.StimulusLocation
Step 2b: AlertSystem.RaiseAlert(SightAlertValue from AIProfile)
Step 2c: Branch on AlertSystem.AlertLevel >= AIProfile.CombatThreshold:
True:
- SetTarget(Stimulus.StimulusLocation → find closest Actor at that location)
- SetAIState(EAIState::Combat)
- Set Blackboard "bHasLOS" = true
False:
- SetAIState(EAIState::Suspicious)
- Set Blackboard "StimulusLocation" = Stimulus.StimulusLocation
- Set Blackboard "bIsInvestigating" = true
Case Hearing:
Step 3a: AlertSystem.RaiseAlert(HearingAlertValue from AIProfile)
Step 3b: StartInvestigation(Stimulus.StimulusLocation)
Step 3c: SetAIState(EAIState::Searching)
Step 3d: Set Blackboard "StimulusLocation" = Stimulus.StimulusLocation
Case Damage:
Step 4a: SetTarget(Stimulus.StimulusLocation → find instigator)
Step 4b: AlertSystem.RaiseAlert(MaxAlertValue)
Step 4c: SetAIState(EAIState::Combat)
Step 4d: Call RequestReinforcements() if team-aware
Step 5: Fire OnTargetAcquired(Stimulus.StimulusLocation nearest Actor) if target found
Nodes: Switch on EAIPerceptionSense, RaiseAlert, Set Blackboard Value, Branch, Find Nearest Actor or Get Actor at Location
SetAIState(NewState: EAIState) → void
[Function: SetAIState]
Step 1: Get old state from Blackboard "AIState"
Step 2: If NewState == OldState → Return
Step 3: Set Blackboard "AIState" = NewState
Step 4: Call StateMachine.SetState(NewState)
Step 5: Fire OnAIStateChanged(OldState, NewState)
Step 6: If NewState == Combat: Call RequestReinforcements()
SetTarget(Target: Actor) → void
[Function: SetTarget]
Step 1: Set Blackboard "TargetActor" = Target
Step 2: If Target is valid:
- Set Blackboard "TargetLocation" = Target.GetActorLocation()
- SetFocus(Target)
- Fire OnTargetAcquired(Target)
Else:
- ClearFocus()
- Fire OnTargetLost()
StartInvestigation(Location: Vector) → void
[Function: StartInvestigation]
Step 1: Set Blackboard "bIsInvestigating" = true
Step 2: Set Blackboard "TargetLocation" = Location
Step 3: Call AI MoveTo(Location)
Step 4: On Move Completed:
- If target not found at location:
- Set Blackboard "bIsInvestigating" = false
- ReturnToPatrol()
RequestReinforcements() → void
[Function: RequestReinforcements]
Step 1: Get all AI_BaseAgentController in radius (ReinforcementRange from AIProfile)
Step 2: ForEach nearby AI:
- If AI.StateMachine.CurrentState == Patrol OR Suspicious:
- Call AI.SetTarget(Self.GetBlackboard("TargetActor"))
- Call AI.SetAIState(Alerted)
Step 3: Fire OnReinforcementRequested(Self.GetActorLocation())
Nodes: Get All Actors of Class (AI_BaseAgentController), ForEachLoop, Get Distance To, Branch, Call SetTarget/SetAIState on other AI
LostSightOfTarget() → void
[Function: LostSightOfTarget]
Step 1: Set Blackboard "bHasLOS" = false
Step 2: Start LostPlayerTimer (timer loops 0.1s)
└─ Each tick: LostPlayerTimer += 0.1
Step 3: Branch on LostPlayerTimer >= AIProfile.LostTargetTimeout:
True:
- ClearTarget()
- SetAIState(EAIState::Searching)
- StartInvestigation(LastKnownPlayerLocation)
- Clear LostPlayerTimer
False: continue waiting
CanSeeTarget() → Boolean
[Function: CanSeeTarget] (Pure)
Step 1: TargetActor = Get Blackboard "TargetActor"
Step 2: If TargetActor NOT valid → Return false
Step 3: Line Trace by Channel from Self location to TargetActor location
- Trace channel: Visibility
- Ignore Self
Step 4: Return (Hit Actor == TargetActor) — true if nothing blocks line of sight
Blueprint Build Checklist
- Create AI_BaseAgentController (Parent: AIController)
- Add all variables from the table above
- Create Blackboard asset: BB_AgentBoard with all key names
- Configure Behavior Tree asset (or use placeholder)
- Implement OnPossess: cache components, init perception/state/alert, run BT
- Implement UpdatePerception: route Sight/Hearing/Damage to correct states
- Implement SetAIState with blackboard update and dispatcher
- Implement SetTarget/ClearTarget with blackboard sync
- Implement StartInvestigation with AI MoveTo
- Implement RequestReinforcements (nearby AI coordination)
- Implement LostSightOfTarget with timeout → search
- Implement CanSeeTarget with line trace
- Create BP_EnemyBase child classes that use this controller