# BPC_AIPerceptionSystem — AI Perception System ## Blueprint Spec — UE 5.5–5.7 --- ### Parent Class `ActorComponent` ### Dependencies - [`AI_BaseAgentController`](AI_BaseAgentController.md) — Owner controller - [`BPC_AlertSystem`](60_BPC_AlertSystem.md) — Alert level processing - `DA_AIProfile` — Perception config - `Engine.AIPerception` — UE5's `UAIPerceptionComponent` (or custom) ### Purpose Encapsulates all sensory perception for AI: sight, hearing, smell, and damage detection. Processes stimulus data, performs line-of-sight checks, applies detection modifiers (lighting, noise, movement speed), and reports findings to the owner [`AI_BaseAgentController`](AI_BaseAgentController.md). Supports configurable sensor ranges, cone angles, and stimulus decay rates. ### Variables | Name | Type | Description | |------|------|-------------| | `SightRange` | Float | Maximum sight distance (cm) | | `SightHalfAngle` | Float | Cone half-angle (degrees) | | `SightLossHalfAngle` | Float | Peripheral angle before losing target | | `HearingRange` | Float | Maximum hearing distance (cm) | | `bUseSight` | Bool | Enable sight perception | | `bUseHearing` | Bool | Enable hearing perception | | `bUseDamageSense` | Bool | React to being damaged | | `DetectionMultiplier_Lighting` | Float | 0.5–2.0 based on ambient light | | `DetectionMultiplier_Movement` | Float | 1.0 standing, 0.3 crouched, 0.1 still | | `DetectionMultiplier_Noise` | Float | Noise volume factor | | `MaxAge` | Float | Seconds before stimulus decays | | `SightDelay` | Float | Time before initial detection | | `bTargetInSight` | Bool | Current LOS status | | `LastSightTime` | Float | Last successful sight check | | `RegisteredStimuli` | Array | Current active stimuli | ### Structs | Struct | Fields | Description | |--------|--------|-------------| | `FStimulusInfo` | Type: EStimulusType, Source: AActor, Location: FVector, Strength: Float, Age: Float, bCurrentlyValid: Bool | A perceived event | ### Enums | Enum | Values | Description | |------|--------|-------------| | `EStimulusType` | Sight, Hearing, Damage, Smell, Vibration | Sensory channel | ### Functions | Name | Inputs | Outputs | Description | |------|--------|---------|-------------| | `InitializePerception` | Config: FPerceptionConfig | — | Set ranges, angles from profile | | `OnSightStimulus` | Target: AActor | Bool | LOS check with modifiers | | `OnHearingStimulus` | Location: FVector, NoiseTag: FGameplayTag, Loudness: Float | — | Sound detection | | `OnDamageStimulus` | Instigator: AActor | — | Direct damage detection | | `PerformLineOfSightCheck` | Target: AActor | Bool | Raycast with channel | | `ApplyDetectionModifiers` | BaseChance: Float | Float | Apply darkness, movement, cover | | `RegisterStimulus` | Info: FStimulusInfo | — | Add to active list | | `ForgetStimulus` | Target: AActor | — | Clear specific source | | `GetDominantStimulus` | — | FStimulusInfo | Highest priority active | | `HasLineOfSightTo` | Target: AActor | Bool | Public wrapper | | `GetSightStrength` | Target: AActor | Float | 0.0–1.0 detection confidence | | `DecayStimuli` | DeltaTime: Float | — | Age all stimuli | ### Event Dispatchers | Name | Parameters | Fired When | |------|-----------|-----------| | `OnTargetDetected` | Target: AActor, Strength: Float, Type: EStimulusType | New target detected | | `OnTargetLost` | Target: AActor | Target out of perception | | `OnLineOfSightChanged` | Target: AActor, bHasLOS: Bool | LOS state change | | `OnSoundHeard` | Location: FVector, Loudness: Float | Sound detected | ### Blueprint Flow ``` [OnSightStimulus] └─► If !bUseSight → return false └─► If Distance > SightRange → return false └─► If Angle > SightHalfAngle → return false (outside cone) └─► // Modifier layer ModChance = ApplyDetectionModifiers(1.0) If Random < ModChance → return false (failed detection check) └─► // LOS check bHasLOS = PerformLineOfSightCheck(Target) If !bHasLOS → return false └─► // Confirmed Strength = CalculateStrength(Distance, Angle, Modifiers) FStimulusInfo = { Sight, Target, Location, Strength, 0, true } RegisterStimulus(Info) Broadcast OnTargetDetected(Target, Strength, Sight) Return true [ApplyDetectionModifiers] └─► BaseChance *= DetectionMultiplier_Lighting (based on light channel) └─► BaseChance *= DetectionMultiplier_Movement (based on target velocity) └─► If target in cover → BaseChance *= 0.3 (partial cover) or 0.0 (full) └─► Return FMath::Clamp(BaseChance, 0.0, 1.0) [PerformLineOfSightCheck] └─► Start = Owner Pawn EyeLocation └─► End = Target.GetActorLocation + Target BaseEyeHeight └─► Hit = LineTraceSingleByChannel(Channel = Visibility) └─► Return Hit.Actor == Target || Hit.Actor == nullptr ``` ### Stimulus Priority Table | Stimulus Type | Base Priority | Decay Rate | Triggers | |---------------|--------------|-----------|----------| | Damage | 100 | Instant forget on lost | Combat state | | Sight (Combat) | 90 | 3 sec | Combat state | | Sight (Suspicious) | 60 | 8 sec | Suspicious state | | Hearing (Loud) | 50 | 5 sec | Investigate | | Hearing (Quiet) | 20 | 10 sec | Brief suspicion | | Vibration | 30 | 2 sec | Alert nearby | ### Communications With | Target | Method | Why | |--------|--------|-----| | [`AI_BaseAgentController`](AI_BaseAgentController.md) | Owner | Send stimulus results | | [`BPC_AlertSystem`](60_BPC_AlertSystem.md) | Get from Owner | Raise alerts based on perception | | [`BP_EnemyBase`](58_BP_EnemyBase.md) | Owner Pawn | Check eye location, movement speed | | World | Direct | Line trace queries | | Audio Manager | Event | Query noise levels | ### Reuse Notes - Entirely data-driven via DA_AIProfile.PerceptionConfig - Detection modifiers allow stealth mechanics (darkness, crouch, cover) - Sight checks use UE5 AIPerception for stimulus system, but LOS logic is custom for accuracy - Hearing range accepts any gameplay-tagged noise source (footsteps, doors, gunshots) - Stimulus decay prevents infinite chase after target disappears - Renamed from `BPC_PerceptionComponent` to `BPC_AIPerceptionSystem` per Master naming convention. - Cross-references updated: `BPC_AIControllerBase` → `AI_BaseAgentController`.