add blueprints
This commit is contained in:
329
docs/blueprints/02-player/14_BPC_CameraStateLayer.md
Normal file
329
docs/blueprints/02-player/14_BPC_CameraStateLayer.md
Normal file
@@ -0,0 +1,329 @@
|
||||
# 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:**
|
||||
1. Store CurrentCameraState as PreviousState
|
||||
2. CurrentCameraState = NewState
|
||||
3. Get S_CameraStateConfig for NewState
|
||||
4. Set CurrentTargetFOV to config.TargetFOV
|
||||
5. Set CameraOffsetTarget to config.HeadOffset
|
||||
6. Set CameraRotationTarget to config.HeadRotation
|
||||
7. Set pitch constraints from config
|
||||
8. Begin blending toward targets over BlendSpeed
|
||||
9. 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:**
|
||||
1. If ShakeRequest.Tag already in ActiveShakeRequests:
|
||||
- If new priority >= existing: replace existing shake
|
||||
- If new priority < existing: ignore
|
||||
2. Ask PlayerCameraManager to play shake
|
||||
3. Store in ActiveShakeRequests
|
||||
4. 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:**
|
||||
1. 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:**
|
||||
1. If bInstant: apply immediately
|
||||
2. Else: start blend over Override.BlendTime
|
||||
3. 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:**
|
||||
1. 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:**
|
||||
1. Delta = CurrentTargetFOV - CurrentFOV
|
||||
2. If Abs(Delta) < 0.1: CurrentFOV = CurrentTargetFOV
|
||||
3. Else: CurrentFOV += Delta * BlendSpeed * DeltaTime
|
||||
4. Apply CurrentFOV to PlayerCameraManager
|
||||
|
||||
#### `BlendCameraOffset (Tick)` → `void`
|
||||
- **Description:** Each tick, blend camera location/rotation toward target.
|
||||
- **Flow:**
|
||||
1. InterpVTo(CameraOffsetTarget) for location
|
||||
2. InterpRTo(CameraRotationTarget) for rotation
|
||||
3. Apply offset to camera boom or view target
|
||||
|
||||
#### `UpdateStressPulse` → `void`
|
||||
- **Description:** If stressed, pulse FOV for uneasy effect.
|
||||
- **Flow:**
|
||||
1. If CurrentCameraState != Stressed: return
|
||||
2. PulseValue = Sin(Time * StressFOVPulseSpeed * PI * 2) * StressFOVPulseAmount
|
||||
3. 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:**
|
||||
1. Get PlayerCameraManager from owner's controller
|
||||
2. Set CurrentFOV = DefaultFOV
|
||||
3. Apply to camera
|
||||
4. Bind to BPC_MovementStateSystem.OnMovementModeChanged
|
||||
5. Bind to BPC_StressSystem.OnStressTierChanged
|
||||
|
||||
### Custom Event: `OnMovementModeChangedHandler`
|
||||
- **Description:** Reacts to movement changes for FOV adjustments.
|
||||
- **Flow:**
|
||||
1. If Sprinting: RequestCameraState(Sprinting)
|
||||
2. If Crouching: RequestCameraState(Crouching)
|
||||
3. If Idle/Walking: RequestCameraState(Default)
|
||||
|
||||
### Custom Event: `OnStressTierChangedHandler`
|
||||
- **Description:** Reacts to stress tier changes for camera effects.
|
||||
- **Flow:**
|
||||
1. If tier >= Panicked: RequestCameraState(Stressed), apply CA post-process
|
||||
2. If tier < Distressed: return to Default camera, clear post-process
|
||||
|
||||
---
|
||||
|
||||
## 7. Blueprint Graph Logic Flow
|
||||
|
||||
```mermaid
|
||||
flowchart TD
|
||||
A[RequestCameraState called] --> B{NewState == Current?}
|
||||
B -->|Yes| C[Return]
|
||||
B -->|No| D[Look up S_CameraStateConfig]
|
||||
D --> E[Set FOV target]
|
||||
E --> F[Set head offset/rotation targets]
|
||||
F --> G[Set pitch constraints]
|
||||
G --> H[Fire OnCameraStateChanged]
|
||||
H --> I[BlendTick: each frame]
|
||||
I --> J[Interp FOV toward target]
|
||||
J --> K[Interp offset toward target]
|
||||
K --> L[Apply to PlayerCameraManager]
|
||||
L --> M{Is Stressed state?}
|
||||
M -->|Yes| N[Apply FOV pulse via sine wave]
|
||||
M -->|No| O[Clear pulse effect]
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 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
|
||||
|
||||
- [ ] FOV blends smoothly between states at configured speed
|
||||
- [ ] Sprinting FOV wider than Default, returns on stop
|
||||
- [ ] Camera shake priority prevents lower-priority shakes from overriding high-priority ones
|
||||
- [ ] Stress pulsing creates smooth FOV oscillation without jitter
|
||||
- [ ] Post-process overrides blend in/out correctly
|
||||
- [ ] Pitch constraints apply correctly in hiding/peeking states
|
||||
- [ ] Multiple state changes are queued — last request wins
|
||||
- [ ] Edge case: Rapid state switching between sprint and crouch transitions smoothly
|
||||
- [ ] Edge case: Camera shake with same tag replaces shake without stacking
|
||||
- [ ] Edge case: ClearPostProcessOverride returns to default with correct blend
|
||||
- [ ] All active shakes stop on component destroy or pawn unpossess
|
||||
|
||||
---
|
||||
|
||||
## 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.
|
||||
|
||||
---
|
||||
|
||||
*Blueprint Spec: Camera State Layer. Conforms to TEMPLATE.md v1.0 — part of the UE5 Modular Game Framework.*
|
||||
Reference in New Issue
Block a user