API Reference
Version: 1.1.0 | Complete reference for all Blueprint functions.
Blueprint Function Library: UERP_MusicHelper
Blueprint-callable functions for controlling the music system. No actor placement needed — functions automatically access the GameInstanceSubsystem.
Layer Control
Push Music Layer
Push Music Layer(WorldContext, LayerName, Music, Priority, LayerMode, VolumeMultiplier, FadeInTime, FadeOutTime, bLooping, bPersistAcrossLevels, Quantization)
Description: Adds a new music layer to the local stack. If a layer with the same name exists, the call is ignored.
Parameters:
Layer Name(Name) - Unique name for this layerMusic(USoundBase) - Sound asset to playPriority(Int) - Higher priority layers play over lower ones (default: 0)Layer Mode(ERP_EMusicLayerMode) - Replace or Additive (default: Replace)Volume Multiplier(Float) - Volume scale (default: 1.0)Fade In Time(Float) - Seconds to fade in (default: 1.0)Fade Out Time(Float) - Seconds to fade out (default: 1.0)bLooping(Boolean) - Loop the music (default: true)bPersistAcrossLevels(Boolean) - Keep playing through level transitions (default: false)Quantization(ERP_EQuantization) - Beat sync: None, Beat, HalfBar, Bar, TwoBars (default: None)
Example:
Event BeginPlay
↓
Push Music Layer
├─ Layer Name: "Exploration"
├─ Music: ExplorationMusic
└─ Priority: 0
Pop Music Layer
Pop Music Layer(WorldContext, LayerName, Quantization)
Description: Removes a music layer by name. The layer fades out using its FadeOutTime.
Parameters:
Layer Name(Name) - Name of the layer to removeQuantization(ERP_EQuantization) - Beat sync (default: None)
Example:
Event OnCombatEnd
↓
Pop Music Layer
├─ Layer Name: "Combat"
└─ Quantization: Bar
Push Music Layer Advanced
Push Music Layer Advanced(WorldContext, Layer)
Description: Push a music layer using a full FERP_MusicLayer struct. Useful when passing layer data from configs or variables.
Parameters:
World Context Object(Object) - World context (automatic in Blueprint)Layer(FERP_MusicLayer) - Complete layer struct with all settings
Clear All Music Layers
Clear All Music Layers(WorldContext)
Description: Immediately stops and removes all active music layers. Use for hard transitions or cleanup.
Parameters:
World Context Object(Object) - World context (automatic in Blueprint)
Usage Example:
Event OnReturnToMainMenu
↓
Clear All Music Layers
Presets
Push Music Preset
Push Music Preset(WorldContext, Preset, bClearExisting, Quantization)
Description: Pushes a reusable music preset asset, which can contain multiple layers.
Parameters:
World Context Object(Object) - World context (automatic in Blueprint)Preset(UERP_MusicLayerPreset) - The preset asset to pushbClear Existing(Boolean) - Clear all layers before pushing preset (default: true)Quantization(ERP_EQuantization) - Beat sync option: None (immediate), Beat, HalfBar, Bar, TwoBars (default: None)
Usage Example:
Event OnEnterDungeon
↓
Push Music Preset
├─ Preset: MC_DungeonAmbiance
├─ Clear Existing: true
└─ Quantization: Bar
Query Functions
Is Layer Active
Is Layer Active(WorldContext, LayerName) → Boolean
Description: Checks if a specific layer is currently active in the stack.
Parameters:
World Context Object(Object) - World context (automatic in Blueprint)Layer Name(Name) - Name of the layer to check
Returns: True if layer exists in the active stack, false otherwise.
Usage Example:
Branch (Is Layer Active "Combat")
True → Continue Combat Logic
False → Start Combat Music
Get Active Layer Names
Get Active Layer Names(WorldContext) → Array\<Name\>
Description: Returns the names of all currently active music layers.
Parameters:
World Context Object(Object) - World context (automatic in Blueprint)
Returns: Array of layer names currently in the stack.
Usage Example:
Get Active Layer Names
↓
For Each Loop (Array)
↓
Print String (Current Layer Name)
Stingers
Play Stinger
Play Stinger(WorldContext, StingerSound, bDuckMusic, DuckVolume, DuckFadeTime, RestoreFadeTime, Quantization)
Description: Plays a short musical accent (stinger) without interrupting background music. Optionally ducks (lowers) music volume during playback. Supports quantization for beat-synced playback.
Parameters:
World Context Object(Object) - World context (automatic in Blueprint)Stinger Sound(Sound Base) - The stinger audio to play (usually short, less than 3 seconds)bDuck Music(Boolean) - Lower background music during stinger (default: true)Duck Volume(Float) - Music volume during stinger, 0.0 to 1.0 (default: 0.3)Duck Fade Time(Float) - Time to fade music down (default: 0.2)Restore Fade Time(Float) - Time to restore music after stinger (default: 0.5)Quantization(ERP_EQuantization) - When to play: None (immediate), Beat, HalfBar, Bar, TwoBars (default: None)
Usage Example:
Event OnAchievementUnlocked
↓
Play Stinger
├─ Stinger Sound: Achievement_Fanfare
├─ Duck Music: true
├─ Duck Volume: 0.3
├─ Duck Fade Time: 0.2
├─ Restore Fade Time: 0.5
└─ Quantization: Beat // Wait for next beat
Play Stinger Advanced
Play Stinger Advanced(WorldContext, Params, Quantization)
Description: Play a stinger using a full FERP_StingerParams struct with optional quantization.
Parameters:
World Context Object(Object) - World context (automatic in Blueprint)Params(FERP_StingerParams) - Complete stinger parameters structQuantization(ERP_EQuantization) - When to play: None (immediate), Beat, HalfBar, Bar, TwoBars (default: None)
Play Stinger At Location
Play Stinger At Location(WorldContext, StingerSound, Location, VolumeMultiplier, PitchMultiplier, AttenuationStartDistance, bDuckMusic, DuckVolume, DuckFadeTime, RestoreFadeTime, Quantization)
Description: Plays a stinger at a specific 3D world location with spatial audio attenuation. Perfect for location-based audio accents like explosions, impact sounds, or environmental musical cues. Maintains all ducking and quantization features.
Parameters:
World Context Object(Object) - World context (automatic in Blueprint)Stinger Sound(Sound Base) - The stinger audio to playLocation(Vector) - World position where the stinger should playVolume Multiplier(Float) - Volume multiplier for the stinger (default: 1.0)Pitch Multiplier(Float) - Pitch multiplier for the stinger (default: 1.0)Attenuation Start Distance(Float) - Distance where attenuation starts in units (default: 100.0)bDuck Music(Boolean) - Lower background music during stinger (default: true)Duck Volume(Float) - Music volume during stinger, 0.0 to 1.0 (default: 0.3)Duck Fade Time(Float) - Time to fade music down (default: 0.2)Restore Fade Time(Float) - Time to restore music after stinger (default: 0.5)Quantization(ERP_EQuantization) - When to play: None (immediate), Beat, HalfBar, Bar, TwoBars (default: None)
Usage Example:
Event OnBombExplode
↓
Get Actor Location → ExplosionLocation
↓
Play Stinger At Location
├─ Stinger Sound: Explosion_Musical_Stinger
├─ Location: ExplosionLocation
├─ Volume Multiplier: 1.0
├─ Pitch Multiplier: 1.0
├─ Attenuation Start Distance: 500.0
├─ Duck Music: true
├─ Duck Volume: 0.3
└─ Quantization: Beat
Use Cases:
- Explosion stingers at specific locations
- Environmental musical cues tied to 3D space
- Combat impact sounds that affect music
- Localized magical effects with musical accents
- World events that should be heard spatially
Stinger Handle API
Return a handle when playing stingers to enable runtime control: pause, resume, stop, volume adjustment, and loop events.
Play Stinger With Handle
Play Stinger With Handle(WorldContext, StingerSound, bDuckMusic, DuckVolume, DuckFadeTime, RestoreFadeTime, Quantization) → StingerHandle
Description: Plays a stinger and returns a handle for runtime control. Use this if you need to pause, resume, stop, or monitor the stinger after playing it.
Parameters:
World Context Object(Object) - World context (automatic in Blueprint)Stinger Sound(Sound Base) - The stinger audio to playbDuck Music(Boolean) - Lower background music during stinger (default: true)Duck Volume(Float) - Music volume during stinger, 0.0 to 1.0 (default: 0.3)Duck Fade Time(Float) - Time to fade music down (default: 0.2)Restore Fade Time(Float) - Time to restore music after stinger (default: 0.5)Quantization(ERP_EQuantization) - When to play: None, Beat, HalfBar, Bar, TwoBars (default: None)
Returns: FERP_StingerHandle - A handle to control the stinger
Usage Example:
Event OnBossHit
↓
Play Stinger With Handle
├─ Stinger Sound: BossHit_Stinger
├─ Duck Music: true
└─ (other parameters...)
↓ [returns StingerHandle]
Store StingerHandle → MyStingerHandle
Play Stinger At Location With Handle
Play Stinger At Location With Handle(WorldContext, StingerSound, Location, VolumeMultiplier, PitchMultiplier, AttenuationStartDistance, bDuckMusic, DuckVolume, DuckFadeTime, RestoreFadeTime, Quantization) → StingerHandle
Description: Plays a 3D stinger at a location and returns a handle for runtime control.
Parameters: Same as Play Stinger At Location, but returns FERP_StingerHandle
Play Stinger Enhanced
Play Stinger Enhanced(WorldContext, Params) → StingerHandle
Description: Plays a stinger with full enhanced parameters including looping support, network sync modes, and returns a handle for control.
Parameters:
World Context Object(Object) - World context (automatic in Blueprint)Params(FERP_EnhancedStingerParams) - Full stinger parameters including:Stinger Sound(Sound Base) - Audio to playbDuck Music(Boolean) - Enable music duckingDuck Volume/Fade Times(Float) - Ducking parametersbLoop(Boolean) - Enable loopingLoop Count(Int) - How many times to loop (0 = infinite)Loop Delay(Float) - Delay between loop iterationsSync Mode(Enum) - Local, Synchronized2D, or Synchronized3DLocation(Vector) - 3D position for Synchronized3D modeVolume/Pitch Multipliers(Float) - 3D audio parametersAttenuation Start Distance(Float) - 3D attenuation distance
Returns: FERP_StingerHandle - A handle to control the stinger
Usage Example (with looping):
Event BeginPlay
↓
Create Enhanced Stinger Params
├─ Stinger Sound: Loop_Stinger
├─ bLoop: true
├─ Loop Count: 3
├─ Loop Delay: 0.5
└─ (other parameters...)
↓
Play Stinger Enhanced
└─ Params: [from above]
↓ [returns StingerHandle]
Store StingerHandle → MyLoopingStinger
Stinger Control Functions
Pause Stinger
Pause Stinger(Handle) → bool
Description: Pauses a playing stinger without stopping it.
Parameters:
Handle(FERP_StingerHandle) - The stinger to pause
Returns: bool - True if successful, false if handle is invalid
Usage:
Pause Stinger
└─ Handle: MyStingerHandle
Resume Stinger
Resume Stinger(Handle) → bool
Description: Resumes a paused stinger.
Parameters:
Handle(FERP_StingerHandle) - The stinger to resume
Returns: bool - True if successful
Stop Stinger
Stop Stinger(Handle, FadeOutTime = 0.5) → bool
Description: Stops a stinger and optionally restores music volume.
Parameters:
Handle(FERP_StingerHandle) - The stinger to stopFade Out Time(Float) - Time to fade out before stopping (default: 0.5)
Returns: bool - True if successful
Usage:
Stop Stinger
├─ Handle: MyStingerHandle
└─ Fade Out Time: 0.3
Set Stinger Volume
Set Stinger Volume(Handle, Volume, FadeTime = 0.3) → bool
Description: Adjust the volume of a playing stinger with optional fading.
Parameters:
Handle(FERP_StingerHandle) - The stingerVolume(Float) - New volume, 0.0 to 1.0Fade Time(Float) - Time to fade to new volume (default: 0.3)
Returns: bool - True if successful
Get Stinger Info
Get Stinger Info(Handle) → StingerInfo, bool
Description: Query information about a playing stinger.
Returns in StingerInfo struct:
Handle(FERP_StingerHandle) - The handleSound(Sound Base) - The audio being playedbIsPaused(Boolean) - Is the stinger paused?Current Volume(Float) - Current volume multiplierLoop Count(Int) - Total loops to play (0 = infinite)Current Loop Index(Int) - Current loop iteration
Returns: bool - True if handle is valid
Is Stinger Playing
Is Stinger Playing(Handle) → bool
Description: Check if a stinger is currently playing (not paused, not finished).
Parameters:
Handle(FERP_StingerHandle) - The stinger to check
Returns: bool - True if currently playing
Stinger Events
On Stinger Completed
Delegate: On Stinger Completed
Parameters: Handle (FERP_StingerHandle) - The stinger that finished
Description: Fired when a stinger finishes playing naturally (or is stopped).
Usage:
Event BeginPlay
↓
Play Stinger With Handle
└─ (store handle)
↓
Bind On Stinger Completed
↓
[Event] On Stinger Completed
├─ Handle received
└─ (handle stinger finished, e.g., cleanup)
On Stinger Loop Completed
Delegate: On Stinger Loop Completed
Parameters:
Handle(FERP_StingerHandle) - The looping stingerLoop Index(Int) - Current loop iteration
Description: Fired each time a looping stinger completes one iteration.
Usage:
Play Stinger Enhanced with bLoop=true, LoopCount=5
↓ (plays 5 times)
[Event] On Stinger Loop Completed fires 5 times
├─ Loop 0, 1, 2, 3, 4
└─ After loop 4, On Stinger Completed also fires
Stinger Volume (AERP_StingerVolume)
A placeable box-collision actor that plays a stinger when the player overlaps it. Yellow wireframe in editor.
Properties:
| Category | Property | Type | Description |
|---|---|---|---|
| Stinger | Sound | Stinger Sound | Sound Base | The stinger audio to play |
| Stinger | Ducking | bDuck Music | Boolean | Lower background music during stinger (default: true) |
| Stinger | Ducking | Duck Volume | Float | Music volume during stinger, 0.0–1.0 (default: 0.3) |
| Stinger | Ducking | Duck Fade Time | Float | Time to fade music down (default: 0.2) |
| Stinger | Ducking | Restore Fade Time | Float | Time to restore music after stinger (default: 0.5) |
| Stinger | Timing | Quantization | Enum | Beat sync: None, Beat, or Bar |
| Stinger | Behavior | Actor Filter Tag | Name | Only trigger for actors with this tag (empty = any) |
| Stinger | Behavior | bTrigger Once | Boolean | Fire only on first overlap (default: false) |
How it works: On BeginOverlap, calls Play Stinger (or the quantized variant) with the configured parameters. If bTriggerOnce is true, disables collision after the first trigger.
Audio Ducking
Enable Audio Ducking
Enable Audio Ducking(WorldContext, AudioComponent, DuckVolume, FadeTime)
Description: Automatically lowers music volume while any audio plays (dialogue, SFX, narration, cutscenes), then restores it when the audio finishes. Binds to the AudioComponent's OnAudioFinished event. Perfect for dialogue, voiceovers, or any sound that should be the focus.
Parameters:
World Context Object(Object) - World context (automatic in Blueprint)Audio Component(Audio Component) - The audio component playing your important audioDuck Volume(Float) - Music volume during audio, 0.0 to 1.0 (default: 0.4)Fade Time(Float) - Fade duration for ducking and restoration (default: 0.3)
Usage Example:
Event OnImportantAudio
↓
Spawn Sound 2D (Your Audio)
↓ [Audio Component output]
Enable Audio Ducking
├─ Audio Component: [from above]
├─ Duck Volume: 0.4
└─ Fade Time: 0.3
Volume Control
Set Master Music Volume
Set Master Music Volume(WorldContext, Volume, FadeTime)
Description: Sets the master volume for all music layers. Affects all active and future layers.
Parameters:
World Context Object(Object) - World context (automatic in Blueprint)Volume(Float) - Master volume 0.0 to 1.0Fade Time(Float) - Fade duration in seconds (default: 0.5)
Usage Example:
Event OnSettingsChanged
↓
Set Master Music Volume
├─ Volume: 0.5
└─ Fade Time: 1.0
Get Master Music Volume
Get Master Music Volume(WorldContext) → float
Description: Returns the current master music volume.
Returns: Float (0.0 - 1.0)
Set Layer Volume
Set Layer Volume(WorldContext, LayerName, Volume, FadeTime)
Description: Set volume of a specific layer independently. Perfect for stem mixing or dynamic intensity control.
Parameters:
World Context Object(Object) - World context (automatic in Blueprint)Layer Name(Name) - Name of layer to adjustVolume(Float) - Layer volume 0.0 to 1.0Fade Time(Float) - Fade duration in seconds (default: 0.5)
Usage Example:
Event OnIntensityIncrease
↓
Set Layer Volume
├─ Layer Name: "Combat_Drums"
├─ Volume: 1.0
└─ Fade Time: 2.0
↓
Set Layer Volume
├─ Layer Name: "Combat_Orchestra"
├─ Volume: 0.8
└─ Fade Time: 2.0
Use Case: Fade drums in/out without stopping layer!
Get Layer Volume
Get Layer Volume(WorldContext, LayerName) → float
Description: Get current volume of a specific layer.
Returns: Float (0.0 - 1.0), or 0.0 if layer not found
Data Structures
FERP_MusicLayer
Defines a single music layer with all its properties.
Fields:
Layer Name(Name) - Unique identifier for this layerMusic(Soft Object Ptr<Sound Base>) - Music asset reference (lazy-loaded)Priority(int32) - Layer priority 0-100 (higher plays first)Layer Mode(ERP_EMusicLayerMode) - Replace or AdditiveVolume Multiplier(float) - Volume 0.0 to 1.0Fade In Time(float) - Fade in duration in secondsFade Out Time(float) - Fade out duration in secondsbLooping(bool) - Loop the musicbPersist Across Levels(bool) - Keep playing during level transitions
FERP_StingerParams
Parameters for playing a stinger.
Fields:
Stinger Sound(Sound Base*) - The stinger audio assetbDuck Music(bool) - Lower background music during stingerDuck Volume(float) - Music volume during stinger (0.0-1.0)Duck Fade Time(float) - Fade time for duckingRestore Fade Time(float) - Fade time for restoration
Enums
ERP_EMusicLayerMode
Defines how a layer interacts with others.
Values:
Replace- Replaces all lower-priority layers. Only one Replace layer plays at a time.Additive- Adds on top of the current Replace layer if priority is high enough.
ERP_EQuantization
Defines when a quantized action should execute.
Values:
None- Execute immediately (no synchronization)Beat- Wait for next beat (1/4 note in 4/4 time)Half Bar- Wait for next half bar (2 beats in 4/4 time)Bar- Wait for next full bar (complete measure)Two Bars- Wait for 2 full bars (8 beats in 4/4 time)
Quartz Beat Synchronization
Quartz Clock Management
Initialize Quartz Clock
InitializeQuartzClock(BPM = 120.0, BeatsPerBar = 4)
Description: Initialize or reconfigure the Quartz clock with new tempo and time signature. Auto-called on subsystem init.
Parameters:
BPM(float) - Beats per minute (30-300, default 120)Beats Per Bar(int32) - Time signature beats (2-16, default 4)
Start Music Clock
StartMusicClock()
Description: Start the Quartz clock. Auto-called on init, rarely needed manually.
Stop Music Clock
StopMusicClock()
Description: Stop the Quartz clock. Use to pause beat synchronization.
Set Clock BPM
SetClockBPM
Description: Change the clock tempo, optionally with smooth transition.
Parameters:
New BPM(float) - Target tempo (30-300)Transition Time(float) - Seconds to ramp to new tempo (0 = immediate)
Example:
Set Clock BPM
├─ New BPM: 180.0
└─ Transition Time: 2.0 ← Ramp over 2 seconds
Is Clock Running
IsClockRunning() → bool
Description: Check if the Quartz clock is currently running.
Returns: True if clock is active, false otherwise.
Quantized Layer Control
Note: These functions are superseded by the
Quantizationparameter on standard Push/Pop functions. UsePush Music Layerwith theQuantizationparameter instead for cleaner code.
Push Music Layer Quantized (Legacy)
PushMusicLayerQuantized(Layer, Quantization = Bar)
Description: Push a music layer that starts on the next musical boundary (beat/bar) for seamless transitions.
⚠️ Deprecated: Use Push Music Layer with Quantization parameter instead.
Parameters:
Layer(FERP_MusicLayer) - Layer to pushQuantization(ERP_EQuantization) - When to start (Beat, HalfBar, Bar, TwoBars)
Example:
Event OnCombatStart
↓
Push Music Layer Quantized
├─ Layer: CombatLayer
└─ Quantization: Bar ← Waits for next bar
Modern Alternative:
Event OnCombatStart
↓
Push Music Layer
├─ Layer Name: "Combat"
├─ Music: CombatMusic
└─ Quantization: Bar ← Same effect, cleaner
Pop Music Layer Quantized (Legacy)
PopMusicLayerQuantized(LayerName, Quantization = Bar)
Description: Remove a music layer on the next musical boundary.
⚠️ Deprecated: Use Pop Music Layer with Quantization parameter instead.
Parameters:
Layer Name(Name) - Name of layer to removeQuantization(ERP_EQuantization) - When to stop (Beat, HalfBar, Bar, TwoBars)
Example:
Event OnCombatEnd
↓
Pop Music Layer Quantized
├─ Layer Name: "Combat"
└─ Quantization: Bar ← Stops on next bar
Modern Alternative:
Event OnCombatEnd
↓
Pop Music Layer
├─ Layer Name: "Combat"
└─ Quantization: Bar ← Same effect, cleaner
Timing Queries
Get Current Beat
GetCurrentBeat() → int32
Description: Get the current beat index within the bar.
Returns: Beat number (1-4 in 4/4 time, 1-3 in 3/4 time, etc.)
Example:
Get Current Beat
↓
Branch (Beat == 1)
└─ True → Spawn VFX on beat 1
Get Current Bar
GetCurrentBar() → int32
Description: Get the current bar (measure) number.
Returns: Bar index (0, 1, 2, 3...)
Example:
Get Current Bar
↓
Branch (Bar % 4 == 0)
└─ True → Boss attack every 4 bars
Get Current BPM
GetCurrentBPM() → float
Description: Get the current tempo.
Returns: BPM value (e.g., 120.0)
Get Time Until Next Beat
GetTimeUntilNextBeat() → float
Description: Calculate seconds until the next beat occurs.
Returns: Time in seconds (e.g., 0.25)
Use Case: Animation timing, rhythm game windows.
Get Time Until Next Bar
GetTimeUntilNextBar() → float
Description: Calculate seconds until the next bar starts.
Returns: Time in seconds (e.g., 1.5)
Quantized Stingers
Play Stinger Quantized
PlayStingerQuantized(StingerSound, Quantization = Beat, bDuckMusic = true, DuckVolume = 0.3)
Description: Play a stinger on the next musical boundary.
Parameters:
Stinger Sound(Sound Base) - Audio to playQuantization(ERP_EQuantization) - When to play (Beat, Bar, etc.)bDuck Music(bool) - Lower music during stingerDuck Volume(float) - Music volume during stinger (0.0-1.0)
Example:
Play Stinger Quantized
├─ Sound: VictoryFanfare
├─ Quantization: Bar
├─ Duck Music: True
└─ Duck Volume: 0.3
Quartz Events
OnBeat
Description: Event fired on every musical beat.
Delegates:
Beat Index(int32) - Current beat (1-4 in 4/4 time)Bar Index(int32) - Current bar numberBPM(float) - Current tempo
Example:
Event BeginPlay
↓
Bind Event to OnBeat
↓
OnBeat(BeatIndex, BarIndex, BPM)
↓
If BeatIndex == 1 (downbeat)
↓
Spawn Flash VFX
OnBar
Description: Event fired at the start of each bar.
Delegates:
Bar Index(int32) - Bar numberBPM(float) - Current tempo
GameplayTag Integration
Control music using GameplayTags for modern tag-driven architecture.
Setup
Create Music Layer Registry
- Right-click Content Browser → Miscellaneous → Data Asset
- Choose MusicLayerRegistry (
UERP_MusicLayerRegistry) - Open asset, add entries to "Tagged Layers" map:
- Key: GameplayTag (e.g.,
Music.Combat) - Value: FERP_MusicLayer (configure layer settings)
- Key: GameplayTag (e.g.,
- Save asset
Configure Project Settings
- Edit → Project Settings → Plugins → Elys Music Engine
- Add your DataAsset(s) to Layer Tag Registries list
- Restart editor
(Success) Registries auto-load on game start, persists entire session.
Tag-Based Functions
Load Tag Registry
LoadTagRegistry(Registry, bAppend = false)
Description: Manually load a music tag registry. Auto-loaded from Project Settings on startup.
Parameters:
Registry(UERP_MusicLayerRegistry*) - DataAsset with tag→layer mappingsbAppend(bool) - Add to existing registry (true) or replace (false)
Use Case: Per-level music registries, DLC music packs.
Note: The class is
UERP_MusicLayerRegistryin C++. In the editor it appears as MusicLayerRegistry.
Push Music Layer By Tag
PushMusicLayerByTag(Tag, Quantization = None)
Description: Push a music layer using its GameplayTag. Fallback to parent tag if exact match not found.
Parameters:
Tag(FGameplayTag) - Tag to search (e.g.,Music.Combat.Boss)Quantization(ERP_EQuantization) - Beat sync option: None (immediate), Beat, HalfBar, Bar, TwoBars (default: None)
Fallback Behavior:
Search: Music.Combat.Boss
→ Not found, try Music.Combat
→ FOUND! (Success) Uses Music.Combat layer
Example:
Event OnCombatStart
↓
Push Music Layer By Tag
├─ Tag: Music.Combat
└─ Quantization: Bar
Advanced Example:
Registry:
Music.Combat → Generic Combat Music
Music.Combat.Boss → Boss-Specific Music
Code:
PushMusicLayerByTag("Music.Combat.Elite")
→ Exact match not found
→ Falls back to "Music.Combat" (Success)
PushMusicLayerByTag("Music.Combat.Boss")
→ Exact match found! (Success)
Pop Music Layer By Tag
PopMusicLayerByTag(Tag, Quantization = None)
Description: Remove active layer by its tag (exact match only).
Parameters:
Tag(FGameplayTag) - Tag of layer to removeQuantization(ERP_EQuantization) - Beat sync option: None (immediate), Beat, HalfBar, Bar, TwoBars (default: None)
⚠️ Important - Tag Usage:
- The tag is only used to look up the layer in the registry
- Both
PushandPopuse the same tag to find the layer - Internally, layers are identified by their
LayerNameproperty
Example:
Registry:
Key: "Music.Combat" → Layer { LayerName: "Battle_Theme" }
✅ PushMusicLayerByTag("Music.Combat") → Finds layer, pushes by LayerName
✅ PopMusicLayerByTag("Music.Combat") → Finds layer, pops by LayerName
💡 How it works: Tags map to layers in the registry, then operations use LayerName internally.
Example:
Event OnCombatEnd
↓
Pop Music Layer By Tag
├─ Tag: Music.Combat
└─ Quantization: Bar
Is Layer Active By Tag
IsLayerActiveByTag(Tag) → bool
Description: Check if a layer with this tag is currently playing.
Returns: True if active, false otherwise.
Example:
Branch: Is Layer Active By Tag("Music.Combat")
├─ True: Skip combat music trigger
└─ False: Push combat music
Get Active Layer Tags
GetActiveLayerTags() → TArray<FGameplayTag>
Description: Get all GameplayTags of currently active layers.
Returns: Array of tags (e.g., [Music.Exploration, Music.Ambience])
Use Case: Debug UI, music state visualization.
Preset Registry System
Control groups of layers (presets) using GameplayTags.
Create Music Preset Registry
- Right-click Content Browser → Miscellaneous → Data Asset
- Choose ERP_MusicPresetRegistry
- Open asset, add entries to "Tagged Presets" map:
- Key: GameplayTag (e.g.,
Music.Location.Dungeon) - Value: ERP_MusicLayerPreset DataAsset
- Key: GameplayTag (e.g.,
- Save asset
Configure Project Settings
- Edit → Project Settings → Game → ERP Music Subsystem
- Set Global Preset Tag Registry to your DataAsset
- Restart editor
(Success) Preset registry auto-loads on game start, persists entire session.
Load Preset Registry
LoadPresetRegistry(Registry, bAppend = false)
Description: Manually load a preset registry. Auto-loaded from Project Settings on startup.
Parameters:
Registry(ERP_MusicPresetRegistry*) - DataAsset with tag→preset mappingsbAppend(bool) - Add to existing registry (true) or replace (false)
Use Case: Per-level preset registries, DLC music packs.
Push Music Preset By Tag
PushMusicPresetByTag(Tag, bClearExisting = false, Quantization = None)
Description: Push all layers from a preset using its GameplayTag. Fallback to parent tag if exact match not found.
Parameters:
Tag(FGameplayTag) - Tag to search (e.g.,Music.Location.Dungeon)bClearExisting(bool) - Clear all existing music before pushing presetQuantization(ERP_EQuantization) - Beat sync option: None (immediate), Beat, HalfBar, Bar, TwoBars (default: None)
Example:
Event OnEnterDungeon
↓
Push Music Preset By Tag
├─ Tag: Music.Location.Dungeon
├─ Clear Existing: false
└─ Quantization: Bar
Use Case: One function call to set up entire music scene (ambient + tension + effects).
Pop Music Preset By Tag
PopMusicPresetByTag(Tag, Quantization = None)
Description: Remove all layers from a preset by its tag. Fallback to parent tag if exact match not found.
Parameters:
Tag(FGameplayTag) - Tag of preset to removeQuantization(ERP_EQuantization) - Beat sync option: None (immediate), Beat, HalfBar, Bar, TwoBars (default: None)
Example:
Event OnExitDungeon
↓
Pop Music Preset By Tag
├─ Tag: Music.Location.Dungeon
└─ Quantization: Bar
Layer vs Preset Registry: When to Use What?
Use Layer Registry (UERP_MusicLayerRegistry) when:
- ✅ Single layer, used once
- ✅ Simple configuration
- ✅ Rapid prototyping
- ✅ No need to reuse elsewhere
Example:
LayerRegistry:
Music.Cutscene.Intro → { Inline layer config }
Use Preset Registry (ERP_MusicPresetRegistry) when:
- ✅ Reusable configuration (even 1 layer!)
- ✅ Multiple layers together (scene setup)
- ✅ Shared across systems (volumes, events, triggers)
- ✅ Need variants (Dungeon_Tense, Dungeon_Calm)
Example:
PresetRegistry:
Music.Location.Dungeon → DA_DungeonPreset
├─ Layer 0: Base Ambience
├─ Layer 1: Dripping Water
└─ Layer 2: Distant Growls
💡 Pro Tip: Presets with 1 layer = Reusable single layer!
GameplayTag Best Practices
Tag Hierarchy Design
Music (Root - never used directly)
├─ Music.Menu (Menu music)
├─ Music.Exploration (Exploration music)
├─ Music.Combat (Generic combat - DEFAULT)
│ ├─ Music.Combat.Boss (Boss-specific)
│ ├─ Music.Combat.Elite (Elite enemy)
│ └─ Music.Combat.Stealth (Stealth combat)
└─ Music.Ambience (Ambient layers)
Rule: Always define parent tags as fallbacks!
Registry Organization
Option 1: Single Global Registry (Recommended)
- One registry with all music tags
- Configure in Project Settings → Plugins → Elys Music Engine → auto-loaded
- Simple, works for 90% of games
Option 2: Per-Level Registries (Advanced)
- Base registry (Project Settings)
- Level-specific registries (load manually)
- Use
LoadTagRegistry(LevelMusic, bAppend=true)
Tag vs. Layer Name
Use Tags when:
- (Success) GAS integration (Gameplay Ability System)
- (Success) Event-driven architecture
- (Success) Dynamic music selection
- (Success) Designer-friendly workflow
Use Layer Names when:
- (Success) Simple projects
- (Success) Known at compile-time
- (Success) No tag infrastructure
Both work! Tags = modern, names = classic.
MetaSound Control
Control MetaSound parameters and triggers on active music layers.
Set MetaSound Parameter
SetMetaSoundParameter(WorldContext, LayerName, ParameterName, Value)
Description: Set a float parameter on a MetaSound layer. For volume mixing, effects, or any exposed float.
Parameters:
World Context Object(Object) - World context (automatic in Blueprint)Layer Name(Name) - Name of active layer with MetaSoundParameter Name(Name) - MetaSound parameter to set (e.g., "Drums_Volume")Value(Float) - Parameter value
Example:
Event OnIntensityChange
↓
Set MetaSound Parameter
├─ Layer Name: "Combat"
├─ Parameter Name: "Drums_Volume"
└─ Value: 0.8
Use Case: Stem mixing, crossfades, effect intensities
Trigger MetaSound Event
TriggerMetaSoundEvent(WorldContext, LayerName, TriggerName)
Description: Trigger an event/trigger parameter on a MetaSound layer. Use for one-shot actions.
Parameters:
World Context Object(Object) - World context (automatic in Blueprint)Layer Name(Name) - Name of active layer with MetaSoundTrigger Name(Name) - MetaSound trigger to fire (e.g., "OnPhase2", "BeatDrop")
Example:
Event OnBossPhase2
↓
Trigger MetaSound Event
├─ Layer Name: "Boss"
└─ Trigger Name: "OnPhase2"
Use Case: Phase transitions, beat drops, musical events
Set MetaSound Bool
SetMetaSoundBool(WorldContext, LayerName, ParameterName, Value)
Description: Set a boolean parameter on a MetaSound layer.
Parameters:
World Context Object(Object) - World context (automatic in Blueprint)Layer Name(Name) - Name of active layer with MetaSoundParameter Name(Name) - MetaSound bool parameter (e.g., "IsIntense")Value(Boolean) - True or False
Example:
Event OnLowHealth
↓
Set MetaSound Bool
├─ Layer Name: "Combat"
├─ Parameter Name: "IsIntense"
└─ Value: true
Use Case: Toggle effects, enable/disable stems, state switches
Set MetaSound Int
SetMetaSoundInt(WorldContext, LayerName, ParameterName, Value)
Description: Set an integer parameter on a MetaSound layer.
Parameters:
World Context Object(Object) - World context (automatic in Blueprint)Layer Name(Name) - Name of active layer with MetaSoundParameter Name(Name) - MetaSound int parameter (e.g., "PhaseIndex")Value(Integer) - Integer value
Example:
Event OnPhaseChange(PhaseNum)
↓
Set MetaSound Int
├─ Layer Name: "Boss"
├─ Parameter Name: "PhaseIndex"
└─ Value: PhaseNum
Use Case: Phase indices, difficulty levels, pattern selectors
MetaSound Setup Example
MetaSound Source: "Combat_Music_Stems"
Exposed Inputs:
- Drums_Volume (Float, 0-1, default: 1.0)
- Bass_Volume (Float, 0-1, default: 1.0)
- Guitar_Volume (Float, 0-1, default: 0.0)
- OnPhase2 (Trigger)
- IsIntense (Bool, default: false)
- PhaseIndex (Int32, default: 1)
Internal Logic:
[Drums Wave] → [Gain: Drums_Volume] ↘
[Bass Wave] → [Gain: Bass_Volume] → [Mixer] → Output
[Guitar Wave]→ [Gain: Guitar_Volume]↗
OnPhase2 Trigger → Crossfade to Phase2 stems
IsIntense == true → Add distortion filter
PhaseIndex → Select stem set
Blueprint Usage:
Event BeginPlay
↓
Push Music Layer
├─ Layer Name: "Combat"
└─ Music: Combat_Music_Stems (MetaSound)
Event OnEnemySpawn
↓
Set MetaSound Parameter ("Combat", "Drums_Volume", 1.0)
↓
Set MetaSound Parameter ("Combat", "Guitar_Volume", 0.8)
Event OnBossPhase2
↓
Trigger MetaSound Event ("Combat", "OnPhase2")
↓
Set MetaSound Bool ("Combat", "IsIntense", true)
↓
Set MetaSound Int ("Combat", "PhaseIndex", 2)
MetaSound Best Practices
Parameter Naming:
- (Success)
Drums_Volume,Bass_Volume- Clear, descriptive - (Avoid)
Vol1,Vol2- Ambiguous
Trigger Naming:
- (Success)
OnPhase2,BeatDrop,ApplyEffect- Action-oriented - (Avoid)
Trigger1,T- Unclear
Parameter Ranges:
- Volumes: 0.0 - 1.0 (or 0.0 - 2.0 for boost)
- Bools: True/False for toggles
- Ints: Phase indices (1, 2, 3), pattern IDs
Performance:
- (Success) Parameter changes are cheap (~0.01ms)
- (Success) Triggers are instant
- (CAUTION) Avoid setting same parameter every frame (cache values)
MetaSound vs Multiple Layers
| Approach | Setup | Control | Sync | Memory |
|---|---|---|---|---|
| Multiple Layers | Fast | Volume only | Can drift | 4× components |
| MetaSound Multi-Input | 10 min | Full control | Perfect | 1 component |
Recommendation: Use MetaSound for stems, multiple layers for separate tracks!
On Beat Event
OnBeat(BeatIndex, BarIndex, BPM)
Description: Delegate that fires on every musical beat.
Parameters:
Beat Index(int32) - Current beat (1-4 in 4/4 time)Bar Index(int32) - Current bar numberBPM(float) - Current tempo
Example:
Event BeginPlay
↓
Bind Event to On Beat
↓
On Beat (Beat=1, Bar, BPM)
↓
Spawn Flash VFX ← Every beat 1
On Bar Event
OnBar(BarIndex, BPM)
Description: Delegate that fires on every bar (measure) start.
Parameters:
Bar Index(int32) - Current bar numberBPM(float) - Current tempo
Example:
Event BeginPlay
↓
Bind Event to On Bar
↓
On Bar (Bar, BPM)
↓
Print String ("Bar {Bar}")
Data Assets
UERP_MusicLayerPreset
Reusable configuration containing multiple music layers.
Fields:
Preset Name(String) - Descriptive name for this configurationLayers(Array<FERP_MusicLayer>) - All layers in this configurationDefault Fade Time(float) - Default fade time for layers without explicit values
Usage: Create in Content Browser → Right-click → Miscellaneous → Data Asset → UERP_MusicLayerPreset
Actors & Components
AERP_MusicVolume
Level-placed music trigger volume with flexible activation modes and content types.
Uses BrushComponent - Shape volume however you want (box, sphere, custom brush)
Volume Modes:
Toggle- Activates on enter, deactivates on exitEnable- Activates on enter onlyDisable- Deactivates on enter only
Content Types:
Single Layer- Push one music layerSingle Preset- Push one presetLayer List- Push multiple layers at oncePreset List- Push multiple presets at onceBy Tag (Layer Registry)- Look up layers from Layer Registry by tag(s)By Tag (Preset Registry)- Look up presets from Preset Registry by tag(s)
Core Properties:
Volume Mode(EERP_MusicVolumeMode) - Toggle/Enable/DisableContent Type(EERP_MusicContentType) - What to activateDisable Mode(EERP_MusicDisableMode) - How to deactivate (ByContent/ByTag/ClearAll)
Single Layer Properties:
Layer Name(Name) - Layer identifierMusic(Sound Base) - Music to playPriority(int32) - Layer priorityLayer Mode(ERP_EMusicLayerMode) - Replace or AdditiveVolume Multiplier(float) - Volume 0.0 to 1.0Fade In Time(float) - Fade in durationFade Out Time(float) - Fade out duration
Single Preset Properties:
Music Preset(UERP_MusicLayerPreset*) - Preset to apply
List Properties:
Music Layers(TArray<FERP_MusicLayer>) - List of layersMusic Presets(TArray<UERP_MusicLayerPreset*>) - List of presets
Tag Properties:
Layer Tags(TArray<FGameplayTag>) - Tags to look up in Layer Registry (ByTagLayers mode)Preset Tags(TArray<FGameplayTag>) - Tags to look up in Preset Registry (ByTagPresets mode)
Advanced Properties:
Actor Filter Tag(FGameplayTag) - Only trigger for actors with this tag (via IGameplayTagAssetInterface)bTrigger Once(bool) - Only trigger the first timebClear Existing Music(bool) - Stop all music before activatingbPersist Across Levels(bool) - Keep music active when changing levels (only for Enable/Toggle modes)
Usage Examples:
- Toggle mode: Place box volume around area - music plays inside, stops outside
- Enable mode: Place sphere at dungeon entrance - activates combat music
- Disable mode: Place sphere at dungeon exit - stops combat music
- Multiple tags: Use ByTagLayers with
[Music.Combat, Music.Tension]to activate multiple layers at once
Subsystem
UERP_MusicSubsystem
GameInstanceSubsystem that manages all music layers. Automatically created by Unreal Engine - no manual setup needed.
Lifetime: Created on game start, persists across levels, destroyed on game shutdown.
Access: All UERP_MusicHelper functions internally use this subsystem. Direct access not needed in Blueprint.
Usage Patterns
Pattern 1: Basic Music Playback
Level BeginPlay
↓
Push Music Layer
├─ Layer Name: "Background"
├─ Music: BackgroundMusic
└─ Priority: 0
Pattern 2: Combat Music System
On Enter Combat
↓
Push Music Layer
├─ Layer Name: "Combat"
├─ Priority: 10
└─ Layer Mode: Replace
On Exit Combat
↓
Pop Music Layer
└─ Layer Name: "Combat"
Pattern 3: Additive Tension Layer
Base exploration playing at Priority 0
↓
On Enemy Nearby
↓
Push Music Layer
├─ Layer Name: "Tension"
├─ Priority: 5
├─ Layer Mode: Additive
└─ Volume: 0.7
Network Synchronization
Overview
The ERP Music Helper sync functions synchronize music and stingers across all multiplayer clients. Late-joiners automatically sync with music already in progress.
All sync helpers work from server or client — automatic routing handles the network.
When to use:
- ✅ Synchronized music in shared areas (boss arenas, events)
- ✅ Late-joiners should hear music at the correct position
- ✅ Stingers for all players (announcements, events)
- ❌ Individual player music (use regular
PushMusicLayer) - ❌ Zone music (use
ERP_MusicVolumewith Network Sync)
Sync Push Music Layer
Sync Push Music Layer(WorldContext, LayerName, Music, Priority, LayerMode, VolumeMultiplier, FadeInTime, FadeOutTime, bLooping, Quantization)
Description: Push a music layer that plays on all clients.
Example:
Sync Push Music Layer
├─ Layer Name: "BossMusic"
├─ Music: BossTheme
└─ Priority: 10
Sync Pop Music Layer
Sync Pop Music Layer(WorldContext, LayerName, Quantization)
Description: Remove a synced music layer from all clients.
Sync Clear All Layers
Sync Clear All Layers(WorldContext)
Description: Remove all synced music layers on all clients.
Sync Push Music Layer By Tag
Sync Push Music Layer By Tag(WorldContext, Tag, Quantization)
Description: Push a synced layer using a GameplayTag from the loaded tag registry.
Example:
Sync Push Music Layer By Tag
└─ Tag: Music.Zone.BossArena
Sync Pop Music Layer By Tag
Sync Pop Music Layer By Tag(WorldContext, Tag, Quantization)
Description: Remove a synced layer by GameplayTag.
Sync Play Stinger
Sync Play Stinger(WorldContext, StingerSound, bDuckMusic, DuckVolume, DuckFadeTime, RestoreFadeTime) → StingerHandle
Description: Play a stinger on all clients.
Returns: FERP_StingerHandle (valid on server, empty on client — handle is assigned server-side).
Sync Stop Stinger
Sync Stop Stinger(WorldContext, Handle)
Description: Stop a synced stinger on all clients.
Music Volume Network Sync
Use ERP_MusicVolume with Network Sync enabled for zone-based synced music — no code required.
- Place
ERP_MusicVolumein your level - Configure music content
- Enable Music | Behavior → Network Sync
Players entering the volume hear music at the correct time offset relative to the server clock.
Best Practices
- Use descriptive layer names - "Combat", "BossFight", "TensionLayer" are clear
- Reserve priority 15+ for special events (bosses, cutscenes)
- Always Pop layers - Prevents memory leaks and layer stack bloat
- Use Replace for main music - Combat, exploration, menu themes
- Use Additive for atmospheres - Tension layers, weather, environmental sounds
- Enable persistence sparingly - Only for music that should span level loads
- Set appropriate fade times - 1-2 seconds for smooth transitions, avoid >5 seconds
Performance Considerations
- System is lightweight: ~10-50 KB memory overhead
- Audio component pooling: automatic, no management needed
- Typical usage: 2-5 active layers (optimal)
- 10+ layers: still fine, consider consolidation if more
- Music assets loaded on-demand via soft references