Files
UE5-Modular-Game-Framework/docs/blueprints/09-ai/84_AI_BaseAgentController.md
Lefteris Notas fef25a3363 Enhance documentation with Manual Implementation Guides and Build Checklists
- 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.
2026-05-19 17:51:03 +03:00

362 lines
14 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# AI_BaseAgentController — AI Controller
## Blueprint Spec — UE 5.55.7
---
### Parent Class
`AIController`
### Dependencies
- [`BP_EnemyBase`](58_BP_EnemyBase.md) — Pawn
- [`BPC_AIPerceptionSystem`](BPC_AIPerceptionSystem.md) — Sensing
- [`BB_AgentBoard`](BB_AgentBoard.md) — Decision-making
- [`BPC_AIStateMachine`](61_BPC_AIStateMachine.md) — High-level states
- [`BPC_AlertSystem`](60_BPC_AlertSystem.md) — Threat awareness
- [`BPC_HealthSystem`](../02-player/08_BPC_HealthSystem.md) — Self health
- [`I_Damageable`](../01-core/03_I_InterfaceLibrary.md) — Damage reception
- `DA_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.01.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`](58_BP_EnemyBase.md) | Possessed pawn | Movement, animation, abilities |
| [`BPC_AIPerceptionSystem`](BPC_AIPerceptionSystem.md) | Get Component | Sensory stimulus processing |
| [`BB_AgentBoard`](BB_AgentBoard.md) | Get Component | Blackboard updates |
| [`BPC_AIStateMachine`](61_BPC_AIStateMachine.md) | Get Component | State transitions |
| [`BPC_AlertSystem`](60_BPC_AlertSystem.md) | Get Component | Threat level queries |
| [`BPC_HealthSystem`](../02-player/08_BPC_HealthSystem.md) | 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_AIControllerBase` to `AI_BaseAgentController` per Master naming convention.
- Cross-references updated: `BPC_PerceptionComponent``BPC_AIPerceptionSystem`, `BPC_BehaviorTreeManager``BB_AgentBoard`, `BPC_HealthComponent``BPC_HealthSystem`.
---
## Manual Implementation Guide
### Class Setup
1. Create Blueprint Class: Parent = `AIController`, Name = `AI_BaseAgentController`
2. Save to: `Content/Framework/AI/`
3. 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