Files
UE5-Modular-Game-Framework/docs/blueprints/09-ai/82_BPC_AlertSystem.md
Lefteris Notas 411edea8ce add blueprints
2026-05-19 13:22:27 +03:00

147 lines
7.1 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.

# 60 — BPC_AlertSystem
## Blueprint Spec — UE 5.55.7
---
### Parent Class
`ActorComponent`
### Dependencies
- [`BPC_AIControllerBase`](55_BPC_AIControllerBase.md) — Owner controller
- [`BP_EnemyBase`](58_BP_EnemyBase.md) — Pawn that receives commands
- [`DA_AIProfile`](../12-content/63_DA_AIProfileDataAsset.md) — Alert thresholds and response times
- [`BPC_PerceptionComponent`](56_BPC_PerceptionComponent.md) — Stimulus input source
- [`BPC_AIStateMachine`](61_BPC_AIStateMachine.md) — State transition triggers
- [`I_Damageable`](../01-foundation/05_I_Damageable.md) — Damage stimulus source
### Purpose
Manages AI threat levels, alert escalation, and reinforcement propagation. Receives stimuli from perception and damage systems, evaluates threat severity, escalates through alert levels (Unaware → Suspicious → Alert → Combat), and notifies nearby AI units. Acts as the central threat-response coordinator for each AI.
### Enums
| Enum | Values | Description |
|------|--------|-------------|
| `EAlertLevel` | Unaware, Suspicious, Alert, Combat | Current alert tier |
| `EAlertCause` | SightStimulus, HearingStimulus, DamageTaken, AllyAlert, Environmental | What triggered the alert |
### Structs
| Struct | Fields | Description |
|--------|--------|-------------|
| `FAlertState` | AlertLevel: EAlertLevel, AlertCause: EAlertCause, LastAlertTime: Float, SourceLocation: FVector, KnownTarget: AActor, bHasValidTarget: Bool, SuspicionValue: Float, CombatTimer: Float | Snapshot of current alert status |
| `FAlertPropagationInfo` | AlertLevel: EAlertLevel, SourceLocation: FVector, Target: AActor, PropagationRadius: Float, Timestamp: Float | Data sent to nearby AI |
### Variables
| Name | Type | Description |
|------|------|-------------|
| `CurrentAlertState` | FAlertState | Live alert tracking |
| `AlertThresholds` | FVector2D | Suspicion threshold X, Combat threshold Y |
| `SuspicionDecayRate` | Float | Points per second lost when no stimulus |
| `SuspicionGrowthRate` | Float | Points per second gained on stimulus |
| `CombatExitDelay` | Float | Time without combat before dropping to Alert |
| `ReinforcementRadius` | Float | Max distance to notify allies |
| `bCanCallReinforcements` | Bool | Permission to propagate |
| `ReinforcementCooldown` | Float | Min seconds between calls |
| `LastReinforcementTime` | Float | Cooldown tracker |
| `bIsInCombat` | Bool | Fast check for combat state |
| `InvestigationTimer` | Float | Time spent investigating last known position |
| `MaxInvestigationTime` | Float | Give up after this long |
### Functions
| Name | Inputs | Outputs | Description |
|------|--------|---------|-------------|
| `EvaluateStimulus` | StimulusType: EAlertCause, Intensity: Float, Location: FVector, Instigator: AActor | — | Process incoming stimulus |
| `CalculateThreatScore` | StimulusType: EAlertCause, Intensity: Float, Distance: Float | Float | Compute weighted threat value |
| `EscalateAlert` | NewLevel: EAlertLevel, Cause: EAlertCause | — | Raise alert level |
| `DeescalateAlert` | — | — | Lower alert level (decay timer) |
| `UpdateSuspicion` | DeltaTime: Float | — | Tick suspicion up/down |
| `CheckAlertTransition` | — | EAlertLevel | Determine if threshold crossed |
| `EnterCombat` | Target: AActor | — | Transition to combat state |
| `ExitCombat` | — | — | Transition out of combat |
| `CallReinforcements` | — | — | Broadcast alert to allies |
| `ReceiveReinforcementCall` | Info: FAlertPropagationInfo | — | Handle ally alert broadcast |
| `GetCurrentAlertLevel` | — | EAlertLevel | Getter for blackboard updates |
| `GetKnownTarget` | — | AActor | Current combat target |
| `IsInCombat` | — | Bool | Combat state check |
| `SetInvestigationPoint` | Location: FVector | — | Mark last known target position |
| `ClearInvestigationPoint` | — | — | Reset investigation |
| `ShouldGiveUpSearch` | — | Bool | Timeout check for investigation |
### Blueprint Flow
```
[EvaluateStimulus]
└─► Calculate Threat Score
└─► If Score > AlertThresholds.Y --> Escalate to Combat
└─► Else If Score > AlertThresholds.X --> Escalate to Suspicious
└─► Else --> Update SuspicionValue (accumulate)
└─► If AlertLevel >= Suspicious:
Set Investigation Point
If AlertLevel == Combat:
Set KnownTarget
EnterCombat
If bCanCallReinforcements:
CallReinforcements
[Event Tick]
└─► UpdateSuspicion(DeltaTime):
If no stimulus:
SuspicionValue -= SuspicionDecayRate * DeltaTime
If SuspicionValue <= 0:
DeescalateAlert (back to Unaware)
If AlertLevel == Combat:
CombatTimer += DeltaTime
If CombatTimer > CombatExitDelay && no damage/stimulus:
ExitCombat -> set AlertLevel = Alert
If AlertLevel == Suspicious:
InvestigationTimer += DeltaTime
If InvestigationTimer > MaxInvestigationTime:
ClearInvestigationPoint
DeescalateAlert
[CallReinforcements]
└─► If (Time - LastReinforcementTime) < ReinforcementCooldown: return
└─► Get all AI controllers within ReinforcementRadius
└─► For each:
Call ReceiveReinforcementCall with current alert info
└─► LastReinforcementTime = CurrentTime
[ReceiveReinforcementCall]
└─► If CurrentAlertLevel >= Info.AlertLevel: ignore (already higher)
└─► Else: EscalateAlert(Info.AlertLevel, Environmental)
Set InvestigationPoint = Info.SourceLocation
If Info.AlertLevel == Combat:
Set KnownTarget = Info.Target
```
### Event Dispatchers
| Name | Delegate Signature | Purpose |
|------|-------------------|---------|
| `OnAlertLevelChanged` | EAlertLevel, EAlertCause | UI, sound, state machine listeners |
| `OnCombatEntered` | AActor Target | Combat music, HUD, behavior tree |
| `OnCombatExited` | — | Combat cleanup |
| `OnReinforcementCalled` | FAlertPropagationInfo | Debug logging, analytics |
| `OnInvestigationStarted` | FVector Location | Sound/investigation music |
| `OnInvestigationEnded` | — | Return to patrol |
### Communications With
| Target | Method | Why |
|--------|--------|-----|
| [`BPC_AIStateMachine`](61_BPC_AIStateMachine.md) | Call | Request state change |
| [`BPC_AIControllerBase`](55_BPC_AIControllerBase.md) | Owner reference | Coordinate BB values |
| [`BPC_PerceptionComponent`](56_BPC_PerceptionComponent.md) | Direct call | Get stimulus data |
| [`BP_EnemyBase`](58_BP_EnemyBase.md) | Owner reference | Trigger combat animations |
| [`WBP_HUD`](../06-ui/36_WBP_HUD.md) | Event dispatcher | Show combat indicator |
| [`BPC_CombatFeedback`](../08-combat/54_BPC_CombatFeedbackComponent.md) | Event dispatcher | Combat music/vignette |
### Reuse Notes
- Attached to AIControllerBase; profiles tune thresholds per enemy type
- Works with any perception system that produces EAlertCause stimuli
- Reinforcement chain prevents infinite loops by comparing alert levels
- Investigation system handles "last seen" behavior without combat
- Decay system ensures AI eventually returns to patrol state