8.9 KiB
8.9 KiB
63 — BPC_FearSystem
Blueprint Spec — UE 5.5–5.7
Parent Class
ActorComponent
Dependencies
GI_GameFramework— Central game instance accessBPC_PlayerMetricsTracker— Player anxiety/stress metricsBPC_DifficultyManager— Fear intensity modifierBPC_StressSystem— Player stress levelBPC_AtmosphereController— Atmosphere responseBPC_AudioManager— Audio feedbackBPC_VFXManager— Visual feedbackBPC_LightingManager— Lighting responseBPC_NarrativeStateSystem— 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 (0–100) | 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 |
Get Owner Component | Track fear history for metrics |
BPC_StressSystem |
Get Owner Component | Stress/fear feedback loop |
BPC_DifficultyManager |
Get Owner Component | Fear intensity modifier |
BPC_AtmosphereController |
Direct call | Atmosphere panic mode |
BPC_AudioManager |
Direct call | Panic audio, fear ambience |
BPC_VFXManager |
Direct call | Visual effects per tier |
BPC_LightingManager |
Direct call | Dynamic lighting response |
SS_UIManager |
Subsystem | HUD fear indicator, panic overlay |
BPC_NarrativeStateSystem |
Get Owner Component | Story-aware fear modifiers |
BPC_HealthSystem |
Get Owner Component | Panic damage if health low |
AI_EnemyControllers |
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