Files
UE5-Modular-Game-Framework/docs/blueprints/10-adaptive/132_SS_AudioManager.md
Lefteris Notas 411edea8ce add blueprints
2026-05-19 13:22:27 +03:00

639 lines
31 KiB
Markdown
Raw 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.

# 132 — MetaSounds Audio Manager (`SS_AudioManager`)
## Purpose
Single entry point for all audio playback in the framework. Every system routes sound through this Game Instance Subsystem instead of calling `UGameplayStatics::PlaySound*` directly. Owns 4 MetaSound buses (SFX, Ambience, Music, Dialogue) → Master Bus, manages room-based reverb zones with crossfade, handles per-category volume from player settings, and accepts gameplay-driven parameter modulation (heart rate, stress, fear, music intensity).
## Dependencies
- **Requires:** `SS_SettingsSystem` (105 — persistent volume settings), `BPC_StateManager` (130 — heart rate + vital signals), `BPC_StressSystem` (10 — stress tier), `BPC_PacingDirector` (98 — music intensity), `BPC_HealthSystem` (08 — player health for muffled audio), `BPC_FearSystem` (90 — fear audio modulation), `DA_AudioSettings` (134 — default config)
- **Required By:** ALL systems that play audio, `BP_RoomAudioZone` (133 — room preset changes), `WBP_SettingsMenu` (57 — volume sliders), `BPC_AudioAtmosphereController` (95 — DEPRECATED, replaced by this)
- **Engine/Plugin Requirements:** MetaSounds plugin (UE 5.5+ default audio engine), GameplayTags plugin
## Class Info
| Property | Value |
|----------|-------|
| **Parent Class** | `GameInstanceSubsystem` |
| **Class Type** | Game Instance Subsystem |
| **Asset Path** | `Content/Framework/Audio/SS_AudioManager.uasset` |
| **Implements Interfaces** | *(none)* |
---
## 1. Enums
### E_AudioBusCategory — Audio Bus Categories (5 values)
```text
Enum Name: E_AudioBusCategory
(DisplayName = "Audio Bus Category")
Values:
SFX = 0 // Sound effects — spatial, occluded, surface-reactive
Ambience = 1 // Environmental background — room tones, weather
Music = 2 // Dynamic music — layers, intensity bands
Dialogue = 3 // VO and character dialogue — ducking priority
Master = 4 // Master output — overall volume
```
---
## 2. Structs
### `S_AudioBusConfig`
| Field | Type | Description |
|-------|------|-------------|
| `BusCategory` | `E_AudioBusCategory` | Which bus this config applies to |
| `DefaultVolume` | `Float` (01) | Default volume (pre-settings) |
| `MetaSoundSource` | `UMetaSoundSource` | The MetaSound patch for this bus |
| `bSpatialized` | `Boolean` | Use 3D spatialization? |
| `AttenuationSettings` | `USoundAttenuation` | Distance falloff curve |
| `MaxConcurrentSounds` | `Integer` | Voice limiting per bus |
| `DuckingPriority` | `Integer` | 0=lowest, 100=highest (dialogue=100) |
| `DuckAmount` | `Float` (01) | How much to duck other buses when this bus plays |
| `SettingsBindingTag` | `GameplayTag` | Tag for settings lookup (e.g., `Settings.Audio.SFXVolume`) |
### `S_RoomAcousticProfile`
| Field | Type | Description |
|-------|------|-------------|
| `RoomPresetName` | `FName` | Identifier for this room preset |
| `ReverbDensity` | `Float` (01) | How dense the reverb reflections are |
| `ReverbDecayTime` | `Float` (seconds) | RT60 decay time |
| `ReverbWetLevel` | `Float` (01) | Wet/dry mix for reverb |
| `ReflectionsDelay` | `Float` (ms) | Pre-delay before reflections start |
| `RoomSizeScale` | `Float` (0.53.0) | Perceived room size |
| `OcclusionMultiplier` | `Float` (01) | How much walls occlude sound (0=fully open, 1=fully blocked) |
| `LowPassCutoff` | `Float` (Hz) | Low-pass filter cutoff (simulates wall filtering) |
| `bApplyToSFX` | `Boolean` | Apply this room to SFX bus? |
| `bApplyToAmbience` | `Boolean` | Apply this room to ambience bus? |
| `bApplyToDialogue` | `Boolean` | Apply this room to dialogue bus? |
| `TransitionTime` | `Float` (seconds) | Crossfade time when entering this room |
---
## 3. Variables
### Configuration (Instance Editable, Expose On Spawn)
| Variable | Type | Default | Category | Description |
|----------|------|---------|----------|-------------|
| `BusConfigs` | `Array<S_AudioBusConfig>` | `[SFX, Ambience, Music, Dialogue]` | `Audio Config` | Configuration per bus |
| `RoomPresets` | `Array<DA_RoomAcousticPreset>` | `DefaultPresets` | `Audio Config` | All room acoustic presets |
| `DefaultRoomPreset` | `DA_RoomAcousticPreset` | `Outdoor` | `Audio Config` | Fallback room preset |
| `AudioSettings` | `DA_AudioSettings` | `Defaults` | `Audio Config` | Data asset with volume defaults and bus config |
### Internal (Private / Protected)
| Variable | Type | Default | Category | Description |
|----------|------|---------|----------|-------------|
| `ActiveRoomPreset` | `DA_RoomAcousticPreset` | `None` | `Room` | Current room acoustic profile |
| `PreviousRoomPreset` | `DA_RoomAcousticPreset` | `None` | `Room` | Previous room (for crossfade) |
| `RoomTransitionProgress` | `Float` | `0.0` | `Room` | Crossfade progress 0→1 |
| `RoomTransitionDuration` | `Float` | `0.0` | `Room` | Current transition time remaining |
| `RoomZoneStack` | `Array<DA_RoomAcousticPreset>` | `Empty` | `Room` | Push/pop stack for nested room zones |
| `bIsMuted` | `Boolean` | `false` | `State` | Global mute toggle |
| `bIsPaused` | `Boolean` | `false` | `State` | Global pause state |
| `BusInstances` | `Map<E_AudioBusCategory, UAudioComponent>` | `Empty` | `Bus` | Active bus audio components |
| `ActiveSFXInstances` | `Array<UAudioComponent>` | `Empty` | `SFX` | Pooled SFX playback instances |
| `SFXPoolSize` | `Integer` | `32` | `SFX` | Max concurrent SFX instances |
| `bIsCrossfading` | `Boolean` | `false` | `Room` | Room transition in progress |
| `ActiveDialogueCount` | `Integer` | `0` | `Dialogue` | Number of active dialogue lines |
---
## 4. Functions
### Public Playback Functions
#### `PlaySFX` → `UAudioComponent`
- **Description:** Play spatial SFX through SFX bus at world location. Surface tag selects material impact variant.
- **Parameters:**
| Param | Type | Description |
|-------|------|-------------|
| `Sound` | `UMetaSoundSource` | The MetaSound source to play |
| `Location` | `FVector` | World position for spatialization |
| `SurfaceTag` | `GameplayTag` (optional) | Physical surface tag for material EQ variant |
- **Blueprint Authority:** Any
- **Flow:**
1. Get or create SFX audio component from pool
2. Set sound to `SFXBus` MetaSound source
3. Set world location
4. If SurfaceTag valid: set `SurfaceEQ` parameter on MetaSound
5. Play audio component
6. Return component reference
#### `PlaySFX2D` → `UAudioComponent`
- **Description:** Play non-spatial SFX through SFX bus (UI sounds, heartbeat).
- **Parameters:**
| Param | Type | Description |
|-------|------|-------------|
| `Sound` | `UMetaSoundSource` | The MetaSound source to play |
- **Blueprint Authority:** Any
- **Flow:** Same as PlaySFX but without world location — 2D playback.
#### `PlayAmbient` → `void`
- **Description:** Crossfade ambient layer on Ambience bus.
- **Parameters:**
| Param | Type | Description |
|-------|------|-------------|
| `Sound` | `UMetaSoundSource` | Ambient layer MetaSound |
| `FadeIn` | `Float` (default 1.0) | Fade-in duration in seconds |
- **Blueprint Authority:** Any
- **Flow:**
1. Get Ambience bus audio component
2. Set new MetaSound source
3. Fade volume from 0 to target over `FadeIn` seconds
4. Route through current room reverb
#### `StopAmbient` → `void`
- **Description:** Fade out current ambient layer.
- **Parameters:**
| Param | Type | Description |
|-------|------|-------------|
| `FadeOut` | `Float` (default 2.0) | Fade-out duration in seconds |
- **Blueprint Authority:** Any
#### `SetMusicLayer` → `void`
- **Description:** Set a music layer with intensity parameter.
- **Parameters:**
| Param | Type | Description |
|-------|------|-------------|
| `LayerIndex` | `Integer` | Which music layer (0-3: Calm/Tense/Action/Climax) |
| `Sound` | `UMetaSoundSource` | MetaSound source for this layer |
| `Intensity` | `Float` (default 0.5) | Layer blend intensity 0-1 |
- **Blueprint Authority:** Any
#### `StopMusicLayers` → `void`
- **Description:** Fade out all music layers.
- **Parameters:**
| Param | Type | Description |
|-------|------|-------------|
| `FadeOut` | `Float` (default 2.0) | Fade-out duration in seconds |
- **Blueprint Authority:** Any
#### `PlayMusicStinger` → `void`
- **Description:** One-shot music stinger on Music bus (overrides layers temporarily).
- **Parameters:**
| Param | Type | Description |
|-------|------|-------------|
| `Stinger` | `UMetaSoundSource` | Stinger MetaSound source |
- **Blueprint Authority:** Any
#### `PlayDialogue` → `void`
- **Description:** Play dialogue line. Ducks other buses by configured amounts.
- **Parameters:**
| Param | Type | Description |
|-------|------|-------------|
| `DialogueSound` | `UMetaSoundSource` | Dialogue MetaSound source |
| `Priority` | `Integer` (default 0) | 0=Bark, 10=Quest, 100=Cinematic |
- **Blueprint Authority:** Any
- **Flow:**
1. If `ActiveDialogueCount >= MaxConcurrentDialogue`, check priority
2. If new priority > lowest active: interrupt lowest, play new
3. Apply ducking: SFX -6dB, Ambience -12dB, Music -18dB
4. Route dialogue through Dialogue bus with spatialization
#### `StopDialogue` → `void`
- **Description:** Stop current dialogue playback.
- **Parameters:**
| Param | Type | Description |
|-------|------|-------------|
| `FadeOut` | `Float` (default 0.5) | Fade-out duration in seconds |
- **Blueprint Authority:** Any
### Public Room Zone Functions
#### `SetRoomPreset` → `void`
- **Description:** Begin room transition with smooth crossfade of reverb/occlusion parameters.
- **Parameters:**
| Param | Type | Description |
|-------|------|-------------|
| `Preset` | `DA_RoomAcousticPreset` | The new room acoustic preset |
- **Blueprint Authority:** Any
- **Flow:**
1. Push current preset onto `RoomZoneStack`
2. Set `PreviousRoomPreset = ActiveRoomPreset`
3. Set `ActiveRoomPreset = Preset`
4. Set `RoomTransitionDuration = Preset.TransitionTime`
5. Set `bIsCrossfading = true`
6. Fire `OnRoomPresetChanged(PreviousPreset, Preset)`
7. Begin per-tick interpolation (see `TickRoomTransition`)
#### `SetRoomPresetInstant` → `void`
- **Description:** Instant room switch — no crossfade. Used for void space entry, cutscenes.
- **Parameters:**
| Param | Type | Description |
|-------|------|-------------|
| `Preset` | `DA_RoomAcousticPreset` | The new room preset to apply immediately |
- **Blueprint Authority:** Any
#### `GetCurrentRoomPreset` → `DA_RoomAcousticPreset`
- **Description:** Returns the currently active room preset.
- **Parameters:** *(none)*
- **Blueprint Authority:** Any (Pure)
#### `PopRoomPreset` → `void`
- **Description:** Restores the previous room from the zone stack. Called by `BP_RoomAudioZone` on overlap end.
- **Parameters:** *(none)*
- **Blueprint Authority:** Any
### Public Settings / Control Functions
#### `SetBusVolume` → `void`
- **Description:** Set volume for a specific bus category. Called from settings menu.
- **Parameters:**
| Param | Type | Description |
|-------|------|-------------|
| `Bus` | `E_AudioBusCategory` | Which bus to adjust |
| `Volume` | `Float` (01) | Target volume |
- **Blueprint Authority:** Any
- **Flow:**
1. Set float parameter `Volume` on the corresponding MetaSound bus
2. Fire `OnBusVolumeChanged`
3. If `Bus == Master`, scale all buses proportionally
#### `GetBusVolume` → `Float`
- **Description:** Get current volume for a specific bus.
- **Parameters:**
| Param | Type | Description |
|-------|------|-------------|
| `Bus` | `E_AudioBusCategory` | Which bus to query |
- **Blueprint Authority:** Any (Pure)
#### `SetMasterMute` → `void`
- **Description:** Mute/unmute all audio globally.
- **Parameters:**
| Param | Type | Description |
|-------|------|-------------|
| `bMuted` | `Boolean` | True to mute, false to unmute |
- **Blueprint Authority:** Any
#### `SetPauseAll` → `void`
- **Description:** Pause/resume all audio (used when pause menu opens/closes).
- **Parameters:**
| Param | Type | Description |
|-------|------|-------------|
| `bPaused` | `Boolean` | True to pause, false to resume |
- **Blueprint Authority:** Any
- **Flow:**
1. Set `bIsPaused = bPaused`
2. Set Paused on all bus audio components
3. Fire `OnAudioPaused(bPaused)`
#### `UpdateGameplayParameter` → `void`
- **Description:** Set a gameplay-driven MetaSound float parameter on the relevant bus.
- **Parameters:**
| Param | Type | Description |
|-------|------|-------------|
| `ParameterName` | `FName` | MetaSound parameter name (e.g., `MusicIntensity`) |
| `Value` | `Float` | Parameter value |
- **Blueprint Authority:** Any
#### `UpdateHeartRateAudio` → `void`
- **Description:** Drives heartbeat SFX tempo and breathing layer intensity from StateManager data.
- **Parameters:**
| Param | Type | Description |
|-------|------|-------------|
| `BPM` | `Float` | Current heart rate in BPM (60-180) |
| `Signal` | `E_PlayerVitalSignals` | Vital signal tier |
- **Blueprint Authority:** Any
- **Flow:**
1. Set `HeartRateBPM` parameter on SFX bus
2. Set `VitalSignal` parameter (0-4 enum as int) on SFX bus
3. If heartbeat SFX not already playing: start looping heartbeat MetaSound
#### `UpdateFearAudio` → `void`
- **Description:** Drives fear-reactive audio modulation from StressSystem + FearSystem.
- **Parameters:**
| Param | Type | Description |
|-------|------|-------------|
| `FearLevel` | `Float` (01) | Current fear intensity |
| `Tier` | `E_StressTier` | Current stress tier |
- **Blueprint Authority:** Any
- **Flow:**
1. Set `FearIntensity` parameter on Ambience + SFX buses
2. Set `StressLevel` parameter on Ambience + Music buses
3. Apply fear effects: subtle pitch drop, reverb increase, random pan jitter
### Internal Functions (Private)
#### `InitializeBuses` → `void`
- **Description:** Create `UAudioComponent` for each bus category and attach MetaSound sources. Called during `Initialize`.
- **Flow:**
1. For each `BusConfig` in `BusConfigs`:
a. Create `UAudioComponent`
b. Set sound to `BusConfig.MetaSoundSource`
c. Configure spatialization from `BusConfig.bSpatialized`
d. Attach attenuation settings
e. Store in `BusInstances` map
2. Apply saved settings volumes to each bus
3. Set `ActiveRoomPreset = DefaultRoomPreset`
#### `TickRoomTransition` → `void`
- **Description:** Called on Tick — interpolates room reverb/occlusion/filter parameters during crossfade.
- **Parameters:**
| Param | Type | Description |
|-------|------|-------------|
| `DeltaTime` | `Float` | Frame time |
- **Flow:**
1. If `!bIsCrossfading`: return
2. `RoomTransitionProgress += DeltaTime`
3. If `RoomTransitionProgress >= RoomTransitionDuration`: clamp to 1.0, set `bIsCrossfading = false`
4. Alpha = `RoomTransitionProgress / RoomTransitionDuration`
5. Interpolate: ReverbDensity, ReverbDecayTime, ReverbWetLevel, ReflectionsDelay, RoomSizeScale, OcclusionMultiplier, LowPassCutoff between `PreviousRoomPreset` and `ActiveRoomPreset`
6. Apply to relevant buses based on `bApplyToSFX` / `bApplyToAmbience` / `bApplyToDialogue` flags
#### `GetOrCreateSFXInstance` → `UAudioComponent`
- **Description:** Pool management — reuse an idle SFX audio component or create a new one. If pool is full (32), cull the oldest instance.
- **Flow:**
1. Find first idle component in `ActiveSFXInstances`
2. If found: return it
3. If pool not full: create new, add to pool, return
4. If pool full: stop oldest active instance, reuse it
#### `ApplyRoomToBus` → `void`
- **Description:** Apply a room preset's reverb/occlusion/filter to a specific bus.
- **Parameters:**
| Param | Type | Description |
|-------|------|-------------|
| `Bus` | `E_AudioBusCategory` | Target bus |
| `Preset` | `DA_RoomAcousticPreset` | Room preset to apply |
#### `ApplySettingsToBus` → `void`
- **Description:** Read saved settings volume from `SS_SettingsSystem` and apply to the bus component.
- **Parameters:**
| Param | Type | Description |
|-------|------|-------------|
| `Bus` | `E_AudioBusCategory` | Target bus |
---
## 5. Event Dispatchers
| Dispatcher | Parameters | Bind Access | Description |
|------------|-----------|-------------|-------------|
| `OnRoomPresetChanged` | `OldPreset: FName`, `NewPreset: FName` | `Public` | Fired when room acoustic profile changes |
| `OnBusVolumeChanged` | `Bus: E_AudioBusCategory`, `Volume: Float` | `Public` | Fired when a bus volume is adjusted |
| `OnAudioPaused` | `bPaused: Boolean` | `Public` | Fired on pause/resume — for visual feedback |
| `OnMasterMuteChanged` | `bMuted: Boolean` | `Public` | Fired when global mute toggles |
| `OnDialogueStarted` | `DialogueSound: UMetaSoundSource`, `Priority: Integer` | `Public` | Fired when dialogue begins (for subtitle triggering) |
| `OnDialogueEnded` | `WasInterrupted: Boolean` | `Public` | Fired when dialogue ends |
---
## 6. Overridden Events / Custom Events
### Event: `Initialize`
- **Description:** Called when subsystem is created. Loads config, initializes buses, binds settings.
- **Flow:**
1. Load `DA_AudioSettings` if assigned
2. Call `InitializeBuses()`
3. Bind to `SS_SettingsSystem.OnSettingChanged` → route volume changes to `SetBusVolume`
4. Enable tick (required for room transition interpolation)
5. Apply saved settings volumes from persistent storage
### Event: `Deinitialize`
- **Description:** Cleanup all audio components and unbind delegates.
- **Flow:**
1. Stop all bus audio components
2. Clear `ActiveSFXInstances` pool
3. Unbind from `SS_SettingsSystem`
4. Set all references to null
---
## 7. Blueprint Graph Logic Flow
### Audio Playback Routing
```mermaid
flowchart TD
A[Any System: PlaySound] --> B[SS_AudioManager.PlaySFX / PlayAmbient / PlayMusic / PlayDialogue]
B --> C{Route by Category}
C -->|SFX| D[SFX Bus MetaSound Source]
C -->|Ambience| E[Ambience Bus MetaSound Source]
C -->|Music| F[Music Bus MetaSound Source]
C -->|Dialogue| G[Dialogue Bus MetaSound Source]
D --> H[Room Zone Reverb]
E --> H
F --> H
G --> H
H --> I[Master Bus]
I --> J[Player Settings Volume Sliders]
J --> K[Audio Output]
L[BPC_StateManager.HeartRate] -->|Parameter| D
M[BPC_StressSystem.StressTier] -->|Parameter| E
N[BPC_PacingDirector.IntensityBand] -->|Parameter| F
O[BPC_AccessibilitySettings] -->|Volume Sliders| I
```
### Settings Flow
```mermaid
sequenceDiagram
participant SM as WBP_SettingsMenu
participant SS as SS_SettingsSystem
participant AM as SS_AudioManager
participant Bus as MetaSound Bus
SM->>SS: SetFloat(Settings.Audio.SFXVolume, 0.8)
SS->>SS: Save to persistent settings
SS->>AM: SetBusVolume(SFX, 0.8)
AM->>Bus: Set Float Parameter 'Volume' = 0.8
Bus->>Bus: Apply to output
Note over AM: On game launch:
AM->>SS: GetFloat(Settings.Audio.SFXVolume)
SS->>AM: 0.8
AM->>Bus: Set Float Parameter 'Volume' = 0.8
```
---
## 8. Mix Bus Architecture
```
┌─────────────────────────────────────────────────────┐
│ MASTER BUS │
│ (MS_MasterBus) │
│ - Master Volume (settings) │
│ - Limiter / Compressor │
│ - Global Mute │
│ - Accessibility: Mono collapse, L/R balance │
│ │
│ ┌──────────────────────────────────────────────┐ │
│ │ SFX BUS (MS_SFXBus) │ │
│ │ - 3D Spatialization │ │
│ │ - Per-source occlusion (line trace) │ │
│ │ - Distance attenuation │ │
│ │ - Surface material EQ (concrete/metal/wood) │ │
│ │ - Heart rate BPM → breathing blend param │ │
│ │ - Max 32 concurrent voices │ │
│ │ - Ducking: -6dB when Dialogue active │ │
│ │ Sub-inputs: │ │
│ │ • WeaponFire (limit 8 voices) │ │
│ │ • Footsteps (limit 4 voices per actor) │ │
│ │ • Impacts (limit 8 voices) │ │
│ │ • UI SFX (2D, no spatialization) │ │
│ └──────────────────────────────────────────────┘ │
│ │
│ ┌──────────────────────────────────────────────┐ │
│ │ AMBIENCE BUS (MS_AmbientBus) │ │
│ │ - Stereo (no 3D) │ │
│ │ - 4-layer crossfade (room tone, wind, drone) │ │
│ │ - Stress tier → layer blend weights │ │
│ │ - Room reverb applied │ │
│ │ - Ducking: -12dB when Dialogue active │ │
│ └──────────────────────────────────────────────┘ │
│ │
│ ┌──────────────────────────────────────────────┐ │
│ │ MUSIC BUS (MS_MusicBus) │ │
│ │ - Stereo (no 3D) │ │
│ │ - 4 intensity layers (Calm/Tense/Action/Climax)│ │
│ │ - PacingDirector.IntensityBand → layer blend │ │
│ │ - Stingers (one-shot overrides) │ │
│ │ - Ducking: -18dB when Dialogue active │ │
│ │ - Combat detected → crossfade to Action │ │
│ └──────────────────────────────────────────────┘ │
│ │
│ ┌──────────────────────────────────────────────┐ │
│ │ DIALOGUE BUS (MS_DialogueBus) │ │
│ │ - 3D (for in-world dialogue) │ │
│ │ - Priority system (Cinematic > Quest > Bark) │ │
│ │ - Ducks all other buses │ │
│ │ - Lip-sync amplitude passthrough │ │
│ │ - Radio/phone EQ preset toggle │ │
│ │ - Max 2 concurrent dialogue voices │ │
│ │ - Settings: DialogueVolume → bus volume │ │
│ └──────────────────────────────────────────────┘ │
└─────────────────────────────────────────────────────┘
```
---
## 9. Settings Integration
### Player-Facing Volume Sliders
| Setting | GameplayTag | Bus Controlled | MetaSound Parameter |
|---------|------------|----------------|---------------------|
| Master Volume | `Settings.Audio.MasterVolume` | Master Bus | `Volume` (01) |
| SFX Volume | `Settings.Audio.SFXVolume` | SFX Bus | `Volume` (01) |
| Music Volume | `Settings.Audio.MusicVolume` | Music Bus | `Volume` (01) |
| Ambience Volume | `Settings.Audio.AmbientVolume` | Ambience Bus | `Volume` (01) |
| Dialogue Volume | `Settings.Audio.DialogueVolume` | Dialogue Bus | `Volume` (01) |
### Accessibility Settings
| Setting | Effect |
|---------|--------|
| Mono Audio | Collapse all buses to mono on Master Bus |
| Subtitle Background Opacity | (UI — not audio, handled by WBP_AccessibilityUI) |
| Audio Cues for UI | Play additional confirmation SFX on button press |
| Left/Right Balance | Pan parameter on Master Bus (for single-ear players) |
| Visual Heartbeat Indicator | Alternative to audio heartbeat for deaf players — UI pulse based on `BPC_StateManager.CurrentHeartRate` |
---
## 10. Gameplay Parameter Modulation
MetaSound parameters driven by gameplay state:
| Parameter Name | Source System | Bus | Range | Effect |
|---------------|--------------|-----|-------|--------|
| `HeartRateBPM` | `BPC_StateManager` (130) | SFX | 60180 | Controls heartbeat SFX tempo + breathing layer intensity |
| `VitalSignal` | `BPC_StateManager` (130) | SFX | 04 (enum) | Selects heartbeat sound variant (normal/elevated/critical/erratic) |
| `StressLevel` | `BPC_StressSystem` (10) | Ambience, Music | 01 | Blends tension layers, adds distortion |
| `FearIntensity` | `BPC_FearSystem` (90) | Ambience, SFX | 01 | Lowers pitch, increases reverb, random pan jitter |
| `MusicIntensity` | `BPC_PacingDirector` (98) | Music | 01 (4 bands) | Crossfades between Calm/Tense/Action/Climax layers |
| `PlayerHealth` | `BPC_HealthSystem` (08) | SFX | 01 | Low-pass filter on all SFX as health drops (muffled hearing) |
| `IsUnderwater` | (Physics volume) | Master | bool | Apply underwater EQ + muffled low-pass |
| `CombatActive` | `BPC_StateManager` (130) | Music | bool | Stinger trigger + immediate intensity ramp |
| `TimeOfDay` | World state | Ambience | 01 (dawn→dusk) | Ambient layer blend (day birds → night crickets) |
---
## 11. Communication Matrix
| Who Talks | How | What Is Sent |
|-----------|-----|-------------|
| Any System | `SS_AudioManager.PlaySFX()` | `UMetaSoundSource`, `FVector Location`, `GameplayTag SurfaceTag` |
| Any System | `SS_AudioManager.PlaySFX2D()` | `UMetaSoundSource` (UI sounds) |
| Any System | `SS_AudioManager.PlayAmbient()` | `UMetaSoundSource`, `Float FadeIn` |
| Any System | `SS_AudioManager.SetMusicLayer()` | `Integer LayerIndex`, `UMetaSoundSource`, `Float Intensity` |
| Any System | `SS_AudioManager.PlayDialogue()` | `UMetaSoundSource`, `Integer Priority` |
| `BP_RoomAudioZone` (133) | `SS_AudioManager.SetRoomPreset()` | `DA_RoomAcousticPreset` |
| `WBP_SettingsMenu` (57) | `SS_SettingsSystem.SetFloat()``SS_AudioManager.SetBusVolume()` | `E_AudioBusCategory`, `Float Volume` |
| `BPC_StateManager` (130) | `SS_AudioManager.UpdateHeartRateAudio()` | `Float BPM`, `E_PlayerVitalSignals` |
| `BPC_StressSystem` (10) | `SS_AudioManager.UpdateFearAudio()` | `Float FearLevel`, `E_StressTier` |
| `BPC_PacingDirector` (98) | `SS_AudioManager.UpdateGameplayParameter("MusicIntensity")` | `Float 01` |
| `BPC_HealthSystem` (08) | `SS_AudioManager.UpdateGameplayParameter("PlayerHealth")` | `Float 01` |
| `SS_AudioManager` | `Dispatcher: OnRoomPresetChanged` | `OldPreset: FName`, `NewPreset: FName` |
| `SS_AudioManager` | `Dispatcher: OnBusVolumeChanged` | `Bus: E_AudioBusCategory`, `Volume: Float` |
| `SS_AudioManager` | `Dispatcher: OnAudioPaused` | `bPaused: Boolean` |
| `SS_AudioManager` | `Dispatcher: OnDialogueStarted` | `UMetaSoundSource`, `Integer Priority` (for subtitle system) |
| `SS_AudioManager` | `WBP_AccessibilityUI` (45) | Heart rate BPM for visual heartbeat indicator |
---
## 12. Migration: Replacing Deprecated BPC_AudioAtmosphereController (95)
| Old (BPC_AudioAtmosphereController) | New (SS_AudioManager) |
|-------------------------------------|----------------------|
| `PlayOneShotSFX(Sound, Location)` | `SS_AudioManager.PlaySFX(Sound, Location)` |
| `PlayAmbientSound(Sound, FadeIn)` | `SS_AudioManager.PlayAmbient(Sound, FadeIn)` |
| `SetMusicLayer(LayerIndex, Sound, Volume)` | `SS_AudioManager.SetMusicLayer(LayerIndex, Sound, Intensity)` |
| `PlayDialogue(DialogueSound)` | `SS_AudioManager.PlayDialogue(DialogueSound, Priority)` |
| `SetReverb(Reverb, WetLevel)` | `SS_AudioManager.SetRoomPreset(Preset)` via `BP_RoomAudioZone` |
| `SetOcclusion(Intensity)` | Automatic — per-source line trace in MetaSound bus |
| `FearReactiveAudioUpdate(Fear, Threshold)` | `SS_AudioManager.UpdateFearAudio(Fear, Tier)` |
| `HandleRoomChange(RoomAcousticPreset)` | `BP_RoomAudioZone.OnActorBeginOverlap` |
| `ActiveAudioPreset` / `TargetAudioPreset` | `SS_AudioManager.ActiveRoomPreset` |
| `Master/SFX/Music/Ambient/DialogueVolumeModifier` | `SS_AudioManager.SetBusVolume()` bound to `SS_SettingsSystem` |
### Phase-Out Strategy
1. **Phase 14a:** Create `SS_AudioManager` + `BP_RoomAudioZone` + all MetaSound patches (CURRENT)
2. **Phase 14b:** Update all 129 systems to call `SS_AudioManager` instead of raw `UGameplayStatics::PlaySound*`
3. **Phase 14c:** Convert all `USoundBase` references to `UMetaSoundSource` in Data Assets
4. **Phase 14d:** Remove `BPC_AudioAtmosphereController` (95) from build
---
## 13. Validation / Testing Checklist
- [ ] `PlaySFX(Sound, Location)` spawns at correct world position with spatialization
- [ ] `PlaySFX2D(Sound)` plays without spatialization (UI sounds)
- [ ] `PlayAmbient(Sound)` crossfades ambient layer smoothly
- [ ] `SetMusicLayer(idx, Sound, intensity)` blends music layers correctly
- [ ] `PlayDialogue(Sound, Priority)` ducks other buses by correct amounts
- [ ] `BP_RoomAudioZone` on overlap → `SetRoomPreset` transitions reverb smoothly
- [ ] Nested room zones use stack correctly (push/pop)
- [ ] Room transition crossfade interpolates reverb parameters
- [ ] `SS_SettingsSystem` volume changes apply to correct bus
- [ ] Master Mute silences all buses
- [ ] Pause/Resume toggles all bus audio components
- [ ] `UpdateHeartRateAudio(BPM)` modulates heartbeat tempo in MetaSound
- [ ] `UpdateFearAudio(0.8, Terrified)` applies fear distortion
- [ ] SFX pooling limits to 32 concurrent (oldest culled when full)
- [ ] Dialogue priority system: higher priority interrupts lower
- [ ] Accessibility mono audio collapses all buses
- [ ] Accessibility L/R balance pans correctly on Master Bus
- [ ] Edge case: Rapid room zone enter/exit doesn't cause audio glitches
- [ ] Edge case: SS_AudioManager handles null MetaSound source gracefully
- [ ] Edge case: Settings loaded before first sound plays (Init order)
- [ ] Edge case: `SetMasterMute(true)` while crossfading — immediate mute
---
## 14. Reuse Notes
- `SS_AudioManager` is the **ONLY** entry point for audio playback. Systems must never call `UGameplayStatics::PlaySound*` directly.
- Game instance subsystem — exists for the entire game session. No per-level reinitialization needed.
- SFX pool of 32 ensures no unbounded audio component creation. Reuse is automatic.
- Room zone stack supports arbitrarily nested zones (room within building within cave).
- All gameplay parameters are soft-referenced — if a source system (e.g., `BPC_PacingDirector`) is not present, `UpdateGameplayParameter` fails gracefully (log warning, no crash).
- MetaSound sources can be hot-reloaded in-editor while the game is running for rapid sound design iteration.
---
*Blueprint Spec: SS_AudioManager — Single entry point for all MetaSounds audio. Replaces BPC_AudioAtmosphereController (95). Architecture document: [`metasounds-audio-system.md`](../../architecture/metasounds-audio-system.md)*