14 — Camera State Layer (BPC_CameraStateLayer)
Purpose
Manages the first-person camera's dynamic behaviour: field-of-view changes based on movement speed, camera shake from impacts/events, head bob intensity, and location offsets for crouch/prone/hide. Centralises all camera-modifying logic so other systems can request camera changes without directly manipulating the camera.
Dependencies
- Requires:
BPC_MovementStateSystem (speed-based FOV), BPC_StressSystem (stress-based distortion)
- Required By:
PC_PlayerController (camera management), BPC_HidingSystem (peek camera offsets), WBP_HUD (post-process materials)
- Engine/Plugin Requirements: Camera Shake patterns, Post-Process Materials, Material Parameter Collections
Class Info
| Property |
Value |
| Parent Class |
ActorComponent |
| Class Type |
Blueprint Component |
| Asset Path |
Content/Framework/Player/BPC_CameraStateLayer |
| Implements Interfaces |
None |
1. Enums
E_CameraState
| Value |
Description |
Default = 0 |
Normal gameplay FOV |
Aiming = 1 |
Zoomed in (weapon aim, inspection) |
Sprinting = 2 |
FOV widened for speed |
Crouching = 3 |
Slight downward offset |
Peeking = 4 |
Offset sideways from cover |
Hiding = 5 |
Constricted FOV, darkness from inside |
Stressed = 6 |
FOV pulsing, chromatic aberration |
Injured = 7 |
FOV wobble, blood tint |
Death = 8 |
Fade to black, camera drop |
Cutscene = 9 |
Fixed camera, no player control |
E_CameraShakePriority
| Value |
Description |
Low = 0 |
Ambient shake (footstep, wind) |
Medium = 1 |
Impact shake (damage, explosion) |
High = 2 |
Critical shake (near-death, supernatural event) |
Cinematic = 3 |
Scripted shake, overrides everything |
2. Structs
S_CameraShakeRequest
| Field |
Type |
Description |
ShakeClass |
TSubclassOf<UCameraShakeBase> |
Camera shake blueprint class |
Scale |
Float |
Intensity scale [0..1] |
Priority |
E_CameraShakePriority |
Priority level |
Duration |
Float |
How long the shake lasts |
bIsLooping |
Boolean |
Whether the shake loops |
Tag |
GameplayTag |
Unique identifier to prevent stacking same shake |
S_CameraStateConfig
| Field |
Type |
Description |
TargetFOV |
Float |
FOV value for this state |
BlendSpeed |
Float |
How fast to blend to this FOV |
HeadOffset |
Vector |
Location offset for head/camera |
HeadRotation |
Rotator |
Rotation offset |
bConstrainPitch |
Boolean |
Limit vertical look in this state |
MinPitch |
Float |
Minimum pitch angle |
MaxPitch |
Float |
Maximum pitch angle |
bEnableHeadBob |
Boolean |
Enable head bob in this state |
HeadBobAmplitude |
Float |
Head bob strength |
HeadBobFrequency |
Float |
Head bob speed |
S_PostProcessOverride
| Field |
Type |
Description |
bOverrideVignette |
Boolean |
Override vignette intensity |
VignetteIntensity |
Float |
Vignette strength [0..1] |
bOverrideChromaticAberration |
Boolean |
Override CA intensity |
ChromaticAberrationIntensity |
Float |
CA strength [0..1] |
bOverrideColorGrading |
Boolean |
Override color grading |
ColorGradingLUT |
Texture |
LUT texture for color grading |
BlendTime |
Float |
Time to blend to new post-process settings |
3. Variables
Configuration (Instance Editable, Expose On Spawn)
| Variable |
Type |
Default |
Category |
Description |
DefaultFOV |
Float |
90.0 |
Camera Config |
Default first-person FOV |
StateConfigs |
Map<E_CameraState, S_CameraStateConfig> |
all states |
Camera Config |
FOV/offset values per state |
DefaultPostProcess |
S_PostProcessOverride |
- |
Camera Config |
Default post-process settings |
BaseHeadBobAmplitude |
Float |
0.1 |
Camera Config |
Default head bob strength |
BaseHeadBobFrequency |
Float |
1.0 |
Camera Config |
Default head bob speed |
SprintFOVMultiplier |
Float |
1.1 |
Camera Config |
FOV multiplied by this when sprinting |
StressFOVPulseAmount |
Float |
5.0 |
Camera Config |
FOV pulse range when stressed (degrees) |
StressFOVPulseSpeed |
Float |
0.5 |
Camera Config |
Speed of stress FOV pulse |
Internal (Private / Protected, No Expose)
| Variable |
Type |
Default |
Category |
Description |
CurrentCameraState |
E_CameraState |
Default |
Camera State |
Active camera state |
CurrentTargetFOV |
Float |
90.0 |
Camera State |
Current FOV target being blended to |
CurrentFOV |
Float |
90.0 |
Camera State |
Actual current FOV |
ActiveShakeRequests |
Map<FName, S_CameraShakeRequest> |
{} |
Camera State |
Active shakes by tag |
HighestShakePriority |
E_CameraShakePriority |
Low |
Camera State |
Current highest priority shake |
CameraOffsetTarget |
Vector |
(0,0,0) |
Camera State |
Target head offset being blended to |
CameraRotationTarget |
Rotator |
(0,0,0) |
Camera State |
Target rotation offset |
bIsPitchConstrained |
Boolean |
false |
Camera State |
Whether pitch is currently constrained |
PostProcessBlendAlpha |
Float |
0.0 |
Camera State |
Current post-process blend |
FOVTimerHandle |
FTimerHandle |
- |
Camera State |
Timer for FOV pulse when stressed |
PlayerCameraManager |
APlayerCameraManager |
None |
Camera State |
Cached camera manager reference |
Replicated (if multiplayer)
| Variable |
Type |
Condition |
Description |
CurrentCameraState |
E_CameraState |
Replicated |
Synced camera state |
4. Functions
Public Functions
RequestCameraState → void
- Description: Sets the camera to a state config. Multiple states can stack; highest priority wins.
- Parameters:
| Param |
Type |
Description |
NewState |
E_CameraState |
Desired camera state |
bImmediate |
Boolean |
Skip blend |
- Blueprint Authority: Any
- Flow:
- Store CurrentCameraState as PreviousState
- CurrentCameraState = NewState
- Get S_CameraStateConfig for NewState
- Set CurrentTargetFOV to config.TargetFOV
- Set CameraOffsetTarget to config.HeadOffset
- Set CameraRotationTarget to config.HeadRotation
- Set pitch constraints from config
- Begin blending toward targets over BlendSpeed
- Fire OnCameraStateChanged
PlayCameraShake → void
- Description: Plays a camera shake, respecting priority to prevent shake stacking.
- Parameters:
| Param |
Type |
Description |
ShakeRequest |
S_CameraShakeRequest |
Shake parameters |
- Flow:
- If ShakeRequest.Tag already in ActiveShakeRequests:
- If new priority >= existing: replace existing shake
- If new priority < existing: ignore
- Ask PlayerCameraManager to play shake
- Store in ActiveShakeRequests
- If Duration > 0: start timer to auto-stop shake after Duration
StopCameraShake → void
- Description: Stops a specific camera shake.
- Parameters:
| Param |
Type |
Description |
ShakeTag |
GameplayTag |
Tag identifying the shake |
- Flow:
- If ShakeTag exists in ActiveShakeRequests:
- Stop the shake in PlayerCameraManager
- Remove from ActiveShakeRequests
ApplyPostProcessOverride → void
- Description: Applies temporary post-process settings (vignette, CA, color grading).
- Parameters:
| Param |
Type |
Description |
Override |
S_PostProcessOverride |
Post-process settings |
bInstant |
Boolean |
If true, blend instantly |
- Flow:
- If bInstant: apply immediately
- Else: start blend over Override.BlendTime
- Update Material Parameter Collection values
ClearPostProcessOverride → void
- Description: Returns post-process to default settings.
- Parameters:
| Param |
Type |
Description |
BlendTime |
Float |
Seconds to blend back to default |
- Flow:
- Blend all post-process parameters to 0 / neutral over BlendTime
GetCameraStateConfig → S_CameraStateConfig
- Parameters:
| Param |
Type |
Description |
State |
E_CameraState |
Which state to query |
- Flow: Return StateConfigs[State]
Protected / Private Functions
BlendToTargetFOV (Tick) → void
- Description: Each tick, blend CurrentFOV toward CurrentTargetFOV.
- Flow:
- Delta = CurrentTargetFOV - CurrentFOV
- If Abs(Delta) < 0.1: CurrentFOV = CurrentTargetFOV
- Else: CurrentFOV += Delta * BlendSpeed * DeltaTime
- Apply CurrentFOV to PlayerCameraManager
BlendCameraOffset (Tick) → void
- Description: Each tick, blend camera location/rotation toward target.
- Flow:
- InterpVTo(CameraOffsetTarget) for location
- InterpRTo(CameraRotationTarget) for rotation
- Apply offset to camera boom or view target
UpdateStressPulse → void
- Description: If stressed, pulse FOV for uneasy effect.
- Flow:
- If CurrentCameraState != Stressed: return
- PulseValue = Sin(Time * StressFOVPulseSpeed * PI * 2) * StressFOVPulseAmount
- CurrentTargetFOV = StateConfigs[Stressed].TargetFOV + PulseValue
5. Event Dispatchers
| Dispatcher |
Parameters |
Bind Access |
Description |
OnCameraStateChanged |
E_CameraState OldState, E_CameraState NewState |
Public |
Fired when camera state changes |
OnFOVChanged |
float OldFOV, float NewFOV |
Public |
Fired when FOV changes |
OnShakeStarted |
GameplayTag ShakeTag, float Scale |
Public |
Fired when a camera shake begins |
OnShakeEnded |
GameplayTag ShakeTag |
Public |
Fired when a camera shake ends |
OnPostProcessChanged |
float Vignette, float ChromaticAb |
Public |
Fired on post-process change |
OnCameraConstrained |
bool bIsConstrained, float MinPitch, float MaxPitch |
Public |
Fired when pitch constraints change |
6. Overridden Events / Custom Events
Event: BeginPlay
- Description: Cache camera manager, set initial FOV, bind to state systems.
- Flow:
- Get PlayerCameraManager from owner's controller
- Set CurrentFOV = DefaultFOV
- Apply to camera
- Bind to BPC_MovementStateSystem.OnMovementModeChanged
- Bind to BPC_StressSystem.OnStressTierChanged
Custom Event: OnMovementModeChangedHandler
- Description: Reacts to movement changes for FOV adjustments.
- Flow:
- If Sprinting: RequestCameraState(Sprinting)
- If Crouching: RequestCameraState(Crouching)
- If Idle/Walking: RequestCameraState(Default)
Custom Event: OnStressTierChangedHandler
- Description: Reacts to stress tier changes for camera effects.
- Flow:
- If tier >= Panicked: RequestCameraState(Stressed), apply CA post-process
- If tier < Distressed: return to Default camera, clear post-process
7. Blueprint Graph Logic Flow
8. Communication Matrix
| Who Talks |
How |
What Is Sent |
BPC_CameraStateLayer |
Dispatcher |
OnCameraStateChanged -> ABP_GASP (anim offset), WBP_HUD (post-process) |
BPC_CameraStateLayer |
Dispatcher |
OnShakeStarted / OnShakeEnded -> BP_AudioManager |
BPC_CameraStateLayer |
Listener |
Binds to BPC_MovementStateSystem.OnMovementModeChanged for FOV |
BPC_CameraStateLayer |
Listener |
Binds to BPC_StressSystem.OnStressTierChanged for distortion |
BPC_CameraStateLayer |
Listener |
Binds to BPC_HealthSystem.OnDamageTaken for injury shake |
External (Any) |
Direct |
Calls PlayCameraShake for any gameplay event |
BPC_HidingSystem |
Direct |
Calls RequestCameraState(Peeking) with peek offset |
BPC_HidingSystem |
Direct |
Calls RequestCameraState(Hiding) with hide FOV |
9. Validation / Testing Checklist
10. Reuse Notes
- Camera shake patterns should be authored as Blueprint Camera Shake classes in Content/Framework/Player/Shakes/.
- Post-process settings use a Material Parameter Collection (MPC_CameraEffects) for real-time parameter updates.
- The stress FOV pulse creates a subtle "unease" effect — pair with audio breathing changes for best results.
- For multiplayer: camera shakes are local-only; state changes replicate for shared visual consistency.
- Custom camera states can be added by extending E_CameraState and adding a config entry.
11. Multiplayer Networking
Replication: State only — effects are local. Camera FOV blending, shake, and post-processing are per-client experiences. Only the state enum syncs.
| Variable |
Condition |
Purpose |
CurrentCameraState |
Replicated |
Synced for shared context (e.g., all players know someone is aiming) |
Authority
RequestCameraState can be called by client; state replicates to all.
PlayCameraShake, ApplyPostProcessOverride, BlendToTargetFOV are local only.
- FOV pulse, head bob, camera offset blending are local only.
Client Prediction
- Camera is inherently local — no prediction needed. State changes replicate for other players' awareness.
Blueprint Spec: Camera State Layer. Conforms to TEMPLATE.md v1.0 — part of the UE5 Modular Game Framework.