Files
Lefteris Notas 411edea8ce add blueprints
2026-05-19 13:22:27 +03:00

182 lines
8.9 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.

# 63 — BPC_FearSystem
## Blueprint Spec — UE 5.55.7
---
### Parent Class
`ActorComponent`
### Dependencies
- [`GI_GameFramework`](../01-core/04_GI_GameFramework.md) — Central game instance access
- [`BPC_PlayerMetricsTracker`](../02-player/15_BPC_PlayerMetricsTracker.md) — Player anxiety/stress metrics
- [`BPC_DifficultyManager`](89_BPC_DifficultyManager.md) — Fear intensity modifier
- [`BPC_StressSystem`](../02-player/10_BPC_StressSystem.md) — Player stress level
- [`BPC_AtmosphereController`](64_BPC_AtmosphereController.md) — Atmosphere response
- [`BPC_AudioManager`](66_BPC_AudioManager.md) — Audio feedback
- [`BPC_VFXManager`](67_BPC_VFXManager.md) — Visual feedback
- [`BPC_LightingManager`](65_BPC_LightingManager.md) — Lighting response
- [`BPC_NarrativeStateSystem`](../07-narrative/38_BPC_NarrativeStateSystem.md) — Story-aware fear triggers
### Purpose
Core fear and anxiety system that manages the player's fear level, fear sources, fear decay, and fear-induced gameplay effects. Acts as the central orchestrator for all horror-related feedback loops — audio, visual, AI behavior, and UI — driven by the player's current fear state and environmental context.
### Variables
| Name | Type | Description |
|------|------|-------------|
| `CurrentFearLevel` | Float (0100) | Current fear value |
| `MaxFearLevel` | Float | Cap for fear (default 100) |
| `FearDecayRate` | Float | Passive fear reduction per second |
| `FearThresholds` | TMap\<EFearThreshold, Float\> | Threshold values for each fear tier |
| `ActiveFearSources` | TArray\<FFearSource\> | Currently contributing fear sources |
| `FearMultiplier` | Float | Global multiplier (from DifficultyManager) |
| `bIsInPanicState` | Bool | Overwhelmed by fear |
| `PanicDuration` | Float | Seconds of panic state |
| `PanicTimer` | Float | Panic countdown |
| `LastIncreaseTime` | Float | When fear last increased |
| `bFearDecayPaused` | Bool | Freeze decay |
| `EnvironmentalFearModifier` | Float | Ambient fear from atmosphere |
| `DarknessFearMultiplier` | Float | Extra fear in dark areas |
| `IsolatedFearMultiplier` | Float | Extra fear when alone |
| `ProximityFearMultiplier` | Float | Extra fear from nearby threats |
| `bIsInSafeZone` | Bool | Safe zone overrides fear |
### Enums
| Enum | Values | Description |
|------|--------|-------------|
| `EFearThreshold` | Calm, Uneasy, Nervous, Afraid, Terrified, Panic | Fear tiers |
### Structs
| Struct | Fields | Description |
|--------|--------|-------------|
| `FFearSource` | SourceName: FName, BaseValue: Float, CurrentValue: Float, DecayDelay: Float, bIsDecaying: Bool, TimeSinceTrigger: Float, Tag: FGameplayTag | Active fear contributor |
| `FFearEvent` | Source: FName, Value: Float, Duration: Float, bInstant: Bool, bStack: Bool, AssociatedTag: FGameplayTag | Incoming fear impulse |
### Functions
| Name | Inputs | Outputs | Description |
|------|--------|---------|-------------|
| `Initialize` | — | — | Setup thresholds, bind events |
| `AddFear` | Event: FFearEvent | — | Add fear from any source |
| `RemoveFearSource` | SourceName: FName | — | Remove specific fear source |
| `ClearAllFear` | — | — | Reset fear to baseline |
| `GetFearLevel` | — | Float | Current fear value |
| `GetFearThreshold` | — | EFearThreshold | Current fear tier |
| `IsInPanic` | — | Bool | Panic state check |
| `SetFearDecayRate` | NewRate: Float | — | Override decay speed |
| `PauseFearDecay` | bPaused: Bool | — | Freeze/unfreeze decay |
| `UpdateEnvironmentalFear` | Modifier: Float | — | Ambient fear contribution |
| `CalculateFearTier` | FearValue: Float | EFearThreshold | Determine current tier |
| `TriggerPanic` | Duration: Float | — | Force panic state |
| `ResolvePanic` | — | — | End panic state early |
| `ApplyFearEffect` | Effect: EFearEffect | — | Gameplay consequences of fear |
### Event Dispatchers
| Name | Parameters | Fired When |
|------|-----------|-----------|
| `OnFearLevelChanged` | NewFear: Float, Threshold: EFearThreshold | Any fear change |
| `OnFearThresholdReached` | Threshold: EFearThreshold | Cross a fear tier boundary |
| `OnPanicStarted` | — | Panic state entered |
| `OnPanicEnded` | — | Panic state ended |
| `OnFearSourceAdded` | Source: FFearSource | New fear source registered |
| `OnFearSourceRemoved` | SourceName: FName | Fear source expired |
### Blueprint Flow
```
[Tick — every frame]
└─► If not bFearDecayPaused AND not bIsInPanicState:
CurrentFearLevel -= FearDecayRate * DeltaTime
Clamp CurrentFearLevel to 0..MaxFearLevel
└─► Process active fear sources:
For each FFearSource in ActiveFearSources:
Source.TimeSinceTrigger += DeltaTime
If Source.TimeSinceTrigger > Source.DecayDelay:
Source.bIsDecaying = true
Source.CurrentValue -= DecayRate * DeltaTime
If Source.CurrentValue <= 0:
Remove from ActiveFearSources
Fire OnFearSourceRemoved
└─► If bIsInPanicState:
PanicTimer -= DeltaTime
If PanicTimer <= 0:
ResolvePanic()
└─► CalculateFearTier(CurrentFearLevel)
└─► If tier changed since last frame:
Fire OnFearThresholdReached(NewThreshold)
[AddFear]
└─► Apply modifiers:
EffectiveValue = Event.Value * FearMultiplier
EffectiveValue *= EnvironmentalFearModifier
EffectiveValue *= DarknessFearModifier (if in dark volume)
EffectiveValue *= IsolatedFearModifier (if no allies)
EffectiveValue *= ProximityFearModifier (if enemies nearby)
└─► If Event.bStack:
Find existing source by Event.Source
If found: Stack.Value += EffectiveValue
Else: Create new FFearSource
└─► Else:
Create new FFearSource with Event parameters
└─► CurrentFearLevel += EffectiveValue
└─► Clamp to MaxFearLevel
└─► Check if panic threshold crossed:
If CurrentFearLevel >= FearThresholds[Panic]:
TriggerPanic(PanicDuration)
└─► Fire OnFearLevelChanged(CurrentFearLevel, CurrentThreshold)
└─► Fire OnFearSourceAdded(NewSource)
[TriggerPanic]
└─► bIsInPanicState = true
└─► PanicTimer = Duration (or PanicDuration default)
└─► ApplyFearEffect(EPanicEffects)
└─► BPC_AtmosphereController.TriggerPanicMode()
└─► BPC_AudioManager.PlayPanicAudio()
└─► BPC_VFXManager.TriggerPanicVFX()
└─► UI: Show panic overlay
└─► Fire OnPanicStarted
[ResolvePanic]
└─► bIsInPanicState = false
└─► CurrentFearLevel = FearThresholds[Terrified] * 0.8
└─► BPC_AtmosphereController.EndPanicMode()
└─► BPC_AudioManager.StopPanicAudio()
└─► Fire OnPanicEnded
[ApplyFearEffect — based on current threshold]
└─► EFearThreshold.Calm: No effects
└─► EFearThreshold.Uneasy: Subtle audio cues, slight camera sway
└─► EFearThreshold.Nervous: UI vignette, breathing sounds, reduced stamina regen
└─► EFearThreshold.Afraid: Visibility distortion, movement speed penalty, aim shake
└─► EFearThreshold.Terrified: Severe vignette, stammering audio, weapon sway
└─► EFearThreshold.Panic: Tunnel vision, audio distortion, sprint penalty, AI gets buffs
```
### Communications With
| Target | Method | Why |
|--------|--------|-----|
| [`BPC_PlayerMetricsTracker`](../02-player/15_BPC_PlayerMetricsTracker.md) | Get Owner Component | Track fear history for metrics |
| [`BPC_StressSystem`](../02-player/10_BPC_StressSystem.md) | Get Owner Component | Stress/fear feedback loop |
| [`BPC_DifficultyManager`](89_BPC_DifficultyManager.md) | Get Owner Component | Fear intensity modifier |
| [`BPC_AtmosphereController`](64_BPC_AtmosphereController.md) | Direct call | Atmosphere panic mode |
| [`BPC_AudioManager`](66_BPC_AudioManager.md) | Direct call | Panic audio, fear ambience |
| [`BPC_VFXManager`](67_BPC_VFXManager.md) | Direct call | Visual effects per tier |
| [`BPC_LightingManager`](65_BPC_LightingManager.md) | Direct call | Dynamic lighting response |
| [`SS_UIManager`](../06-ui/32_SS_UIManager.md) | Subsystem | HUD fear indicator, panic overlay |
| [`BPC_NarrativeStateSystem`](../07-narrative/38_BPC_NarrativeStateSystem.md) | Get Owner Component | Story-aware fear modifiers |
| [`BPC_HealthSystem`](../02-player/08_BPC_HealthSystem.md) | Get Owner Component | Panic damage if health low |
| [`AI_EnemyControllers`](../09-ai/55_BPC_AIControllerBase.md) | Event Dispatcher | AI aggression rise with player fear |
### Reuse Notes
- Single instance on player character (or PlayerController)
- All fear sources are stackable and independently decayable
- Thresholds are designer-configurable at runtime
- Fear multiplier from DifficultyManager allows difficulty to scale horror
- Safe zones (checkpoints, safe rooms) pause fear accumulation and decay
- Panic state is a temporary debuff with full cleanup on resolve
- UI reads OnFearLevelChanged dispatcher, never polls