258 lines
11 KiB
Markdown
258 lines
11 KiB
Markdown
# 13 — Embodiment System (`BPC_EmbodimentSystem`)
|
|
|
|
## Purpose
|
|
Creates a sense of first-person body awareness — the player can see their own body, shadow, arms, and legs in appropriate contexts. Manages body visibility, shadow casting, limb IK, and environmental body interactions (body brushing against walls, water drip on arms, blood spatter on hands).
|
|
|
|
## Dependencies
|
|
- **Requires:** `BPC_MovementStateSystem` (posture affects body visibility), `BPC_HealthSystem` (blood spatter based on damage)
|
|
- **Required By:** `BPC_CameraStateLayer` (head height offsets), `BP_PlayerCharacter` (component composition)
|
|
- **Engine/Plugin Requirements:** GASP (arms animation), Material Parameter Collections (blood/water overlays)
|
|
|
|
## Class Info
|
|
| Property | Value |
|
|
|----------|-------|
|
|
| **Parent Class** | `ActorComponent` |
|
|
| **Class Type** | Blueprint Component |
|
|
| **Asset Path** | `Content/Framework/Player/BPC_EmbodimentSystem` |
|
|
| **Implements Interfaces** | None |
|
|
|
|
---
|
|
|
|
## 1. Enums
|
|
|
|
### `E_BodyVisibilityMode`
|
|
| Value | Description |
|
|
|-------|-------------|
|
|
| `FullBody = 0` | Full body visible (third person, mirrors, death) |
|
|
| `ArmsOnly = 1` | Only arms/hands visible (default first person) |
|
|
| `ArmsAndShadow = 2` | Arms + body shadow visible on ground |
|
|
| `Minimal = 3` | Only hands visible (high stress, underwater) |
|
|
| `Hidden = 4` | Body fully hidden (cutscene, UI menu) |
|
|
|
|
### `E_BodyOverlayState`
|
|
| Value | Description |
|
|
|-------|-------------|
|
|
| `Clean = 0` | No overlays |
|
|
| `BloodSpatter = 1` | Blood on hands/arms |
|
|
| `WaterDroplets = 2` | Water on arms/camera |
|
|
| `Mud = 3` | Mud/dirt on body |
|
|
| `Toxic = 4` | Green/glowing contamination |
|
|
|
|
---
|
|
|
|
## 2. Structs
|
|
|
|
### `S_BodyOverlay`
|
|
| Field | Type | Description |
|
|
|-------|------|-------------|
|
|
| `OverlayType` | `E_BodyOverlayState` | Which overlay to apply |
|
|
| `MaterialParameter` | `FName` | Parameter name on the material |
|
|
| `TargetValue` | `Float` | Target intensity [0..1] |
|
|
| `BlendSpeed` | `Float` | How fast to blend to target |
|
|
| `Duration` | `Float` | How long the overlay lasts before fading |
|
|
|
|
### `S_BodyPartVisibility`
|
|
| Field | Type | Description |
|
|
|-------|------|-------------|
|
|
| `bShowArms` | `Boolean` | Whether arms are visible |
|
|
| `bShowLegs` | `Boolean` | Whether legs are visible |
|
|
| `bShowShadow` | `Boolean` | Whether body shadow is visible |
|
|
| `bShowTorso` | `Boolean` | Whether torso is visible (mirrors) |
|
|
|
|
---
|
|
|
|
## 3. Variables
|
|
|
|
### Configuration (Instance Editable, Expose On Spawn)
|
|
|
|
| Variable | Type | Default | Category | Description |
|
|
|----------|------|---------|----------|-------------|
|
|
| `DefaultVisibility` | `E_BodyVisibilityMode` | `ArmsOnly` | `Embodiment Config` | Default visibility for normal gameplay |
|
|
| `ArmsMesh` | `SkeletalMeshComponent` | `None` | `Embodiment Config` | First-person arms mesh reference |
|
|
| `BodyShadowComponent` | `UShadowComponent` | `None` | `Embodiment Config` | Shadow-only body component |
|
|
| `bEnableBodyBrushing` | `Boolean` | `true` | `Embodiment Config` | Arms react to nearby walls |
|
|
| `BrushTraceDistance` | `Float` | `30.0` | `Embodiment Config` | Distance to trace for wall detection |
|
|
| `OverlayBlendGlobalSpeed` | `Float` | `2.0` | `Embodiment Config` | Default blend speed for all overlays |
|
|
|
|
### Internal (Private / Protected, No Expose)
|
|
|
|
| Variable | Type | Default | Category | Description |
|
|
|----------|------|---------|----------|-------------|
|
|
| `CurrentVisibility` | `E_BodyVisibilityMode` | `ArmsOnly` | `Embodiment State` | Current visibility mode |
|
|
| `CurrentOverlay` | `E_BodyOverlayState` | `Clean` | `Embodiment State` | Current active overlay |
|
|
| `OverlayIntensity` | `Float` | `0.0` | `Embodiment State` | Current overlay intensity [0..1] |
|
|
| `bIsNearWall` | `Boolean` | `false` | `Embodiment State` | Whether wall is near for arm brushing |
|
|
| `LastOverLayTime` | `Float` | `0.0` | `Embodiment State` | When last overlay was applied |
|
|
| `ActiveOverlays` | `Map<E_BodyOverlayState, S_BodyOverlay>` | `{}` | `Embodiment State` | Currently active overlays with blend info |
|
|
| `OverlayTimerHandle` | `FTimerHandle` | `-` | `Embodiment State` | Timer for overlay fade-out |
|
|
|
|
### Replicated (if multiplayer)
|
|
|
|
| Variable | Type | Condition | Description |
|
|
|----------|------|-----------|-------------|
|
|
| `CurrentVisibility` | `E_BodyVisibilityMode` | `Replicated` | Synced visibility mode |
|
|
| `CurrentOverlay` | `E_BodyOverlayState` | `Replicated` | Synced overlay state |
|
|
|
|
---
|
|
|
|
## 4. Functions
|
|
|
|
### Public Functions
|
|
|
|
#### `SetVisibilityMode` → `void`
|
|
- **Description:** Sets body visibility mode and toggles mesh components.
|
|
- **Parameters:**
|
|
| Param | Type | Description |
|
|
|-------|------|-------------|
|
|
| `NewMode` | `E_BodyVisibilityMode` | Desired visibility mode |
|
|
| `bInstant` | `Boolean` | If true, skip fade transition |
|
|
- **Flow:**
|
|
1. CurrentVisibility = NewMode
|
|
2. Apply S_BodyPartVisibility based on NewMode
|
|
3. Set ArmsMesh visibility based on bShowArms
|
|
4. Set BodyShadowComponent visibility based on bShowShadow
|
|
5. Fire OnVisibilityModeChanged
|
|
|
|
#### `ApplyOverlay` → `void`
|
|
- **Description:** Applies a body overlay (blood, water, mud) with blend.
|
|
- **Parameters:**
|
|
| Param | Type | Description |
|
|
|-------|------|-------------|
|
|
| `Overlay` | `S_BodyOverlay` | Overlay to apply |
|
|
- **Flow:**
|
|
1. Add or update ActiveOverlays[Overlay.OverlayType]
|
|
2. Start blend toward TargetValue at Overlay.BlendSpeed
|
|
3. If Overlay.Duration > 0: start timer to fade out after Duration
|
|
4. Update material parameter on ArmsMesh
|
|
5. Fire OnOverlayChanged
|
|
|
|
#### `ClearOverlay` → `void`
|
|
- **Description:** Clears a specific overlay or all overlays.
|
|
- **Parameters:**
|
|
| Param | Type | Description |
|
|
|-------|------|-------------|
|
|
| `OverlayType` | `E_BodyOverlayState` | Type to clear; None = clear all |
|
|
- **Flow:**
|
|
1. If OverlayType specified: remove single overlay, blend intensity to 0
|
|
2. If OverlayType == None: clear all overlays, reset to Clean
|
|
3. Update material parameters
|
|
4. Fire OnOverlayChanged
|
|
|
|
#### `CheckWallProximity` → `void`
|
|
- **Description:** Traces forward from camera to detect nearby walls for arm brushing.
|
|
- **Flow:**
|
|
1. Perform line trace from camera forward by BrushTraceDistance
|
|
2. If hit: bIsNearWall = true, apply arm IK offset
|
|
3. If no hit: bIsNearWall = false, relax arm IK
|
|
4. Fire OnWallProximityChanged
|
|
|
|
#### `GetBodyPartVisibility` → `S_BodyPartVisibility`
|
|
- **Description:** Returns current visibility state for all body parts.
|
|
- **Flow:** Return struct derived from CurrentVisibility
|
|
|
|
### Protected / Private Functions
|
|
|
|
#### `ApplyOverlayBlendTick` → `void`
|
|
- **Description:** Called each tick — blends all active overlay material parameters.
|
|
- **Flow:**
|
|
1. For each ActiveOverlay: blend material parameter toward TargetValue
|
|
2. If blend complete and Duration expired: begin fade to 0
|
|
3. Set material parameters on ArmsMesh
|
|
|
|
---
|
|
|
|
## 5. Event Dispatchers
|
|
|
|
| Dispatcher | Parameters | Bind Access | Description |
|
|
|------------|-----------|-------------|-------------|
|
|
| `OnVisibilityModeChanged` | `E_BodyVisibilityMode OldMode`, `E_BodyVisibilityMode NewMode` | `Public` | Fired when body visibility changes |
|
|
| `OnOverlayChanged` | `E_BodyOverlayState CurrentOverlay`, `float Intensity` | `Public` | Fired when overlay state changes |
|
|
| `OnWallProximityChanged` | `bool bIsNearWall`, `float Distance` | `Public` | Fired when wall proximity changes |
|
|
| `OnBodyPartHit` | `FName BoneName`, `S_DamageEvent DamageEvent` | `Public` | Fired when a visible body part is hit |
|
|
|
|
---
|
|
|
|
## 6. Overridden Events / Custom Events
|
|
|
|
### Event: `BeginPlay`
|
|
- **Description:** Caches mesh references, sets initial visibility.
|
|
- **Flow:**
|
|
1. Find ArmsMesh on owner (first-person skeletal mesh)
|
|
2. Find BodyShadowComponent
|
|
3. Set initial visibility to DefaultVisibility
|
|
4. Bind to BPC_HealthSystem.OnDamageTaken for blood overlay
|
|
5. Start wall proximity tick if bEnableBodyBrushing
|
|
|
|
### Custom Event: `OnDamageTakenBloodHandler`
|
|
- **Description:** Applies blood spatter overlay when player takes damage.
|
|
- **Flow:**
|
|
1. Intensity = FMath::Min(DamageEvent.BaseAmount / 50.0, 1.0)
|
|
2. Build S_BodyOverlay with BloodSpatter type
|
|
3. Call ApplyOverlay
|
|
|
|
### Custom Event: `OnEnterWaterHandler`
|
|
- **Description:** Fired when player enters water volume.
|
|
- **Flow:**
|
|
1. Apply WaterDroplets overlay with fast blend and short duration
|
|
2. Start drying timer for overlay fade
|
|
|
|
---
|
|
|
|
## 7. Blueprint Graph Logic Flow
|
|
|
|
```mermaid
|
|
flowchart TD
|
|
A[SetVisibilityMode called] --> B{NewMode == Current?}
|
|
B -->|Yes| C[Return]
|
|
B -->|No| D[Determine BodyPartVisibility]
|
|
D --> E{NewMode == ArmsOnly?}
|
|
E -->|Yes| F[Enable Arms, disable shadow/torso]
|
|
E -->|No| G{NewMode == FullBody?}
|
|
G -->|Yes| H[Enable all body parts]
|
|
G -->|No| I{NewMode == Hidden?}
|
|
I -->|Yes| J[Disable all meshes]
|
|
I -->|No| K[Apply partial visibility]
|
|
F --> L[Fire OnVisibilityModeChanged]
|
|
H --> L
|
|
J --> L
|
|
K --> L
|
|
```
|
|
|
|
---
|
|
|
|
## 8. Communication Matrix
|
|
|
|
| Who Talks | How | What Is Sent |
|
|
|-----------|-----|-------------|
|
|
| `BPC_EmbodimentSystem` | `Dispatcher` | `OnVisibilityModeChanged` -> `BPC_CameraStateLayer` (FOV adjust) |
|
|
| `BPC_EmbodimentSystem` | `Dispatcher` | `OnOverlayChanged` -> `WBP_HUD` (screen effects), `BP_AudioManager` |
|
|
| `BPC_EmbodimentSystem` | `Dispatcher` | `OnWallProximityChanged` -> `ABP_Arms` (IK offset) |
|
|
| `BPC_HealthSystem` | `Listener` | `OnDamageTaken` triggers blood overlay |
|
|
| `External (BP_WaterVolume)` | `Direct` | Calls `ApplyOverlay` for water effects |
|
|
|
|
---
|
|
|
|
## 9. Validation / Testing Checklist
|
|
|
|
- [ ] Visibility modes correctly toggle mesh component visibility
|
|
- [ ] Blood overlay appears on damage and fades over time
|
|
- [ ] Water overlay appears on water entry and dries gradually
|
|
- [ ] Wall proximity trace correctly detects nearby walls
|
|
- [ ] Arm IK offsets apply when wall is detected
|
|
- [ ] Edge case: Rapid visibility mode changes do not cause rendering glitches
|
|
- [ ] Edge case: Multiple overlays stack correctly (blood + water = combined)
|
|
- [ ] Edge case: Hidden mode hides all body components regardless of other settings
|
|
|
|
---
|
|
|
|
## 10. Reuse Notes
|
|
|
|
- The overlay system uses Material Parameter Collections — the implementation should expose scalar parameters for blood/water/mud blend amounts.
|
|
- Wall proximity uses a simple line trace; more advanced IK requires the arms animation blueprint.
|
|
- For third-person modes, use a separate full-body skeletal mesh instead of the arms mesh.
|
|
- Overlay intensity can be driven by gameplay values: more damage = more blood, longer swim = more water.
|
|
- The body shadow component is a separate capsule with a shadow-only material — not a full character mesh.
|
|
|
|
---
|
|
|
|
*Blueprint Spec: Embodiment System. Conforms to TEMPLATE.md v1.0 — part of the UE5 Modular Game Framework.* |