Skip to main content

Advanced Features

MetaSound integration, Quartz beat synchronization, and GameplayTag-driven music.

NOTE: Prerequisites Read the User Guide first — you should be comfortable with layers, priorities, and modes.


MetaSound Integration

MetaSounds unlock advanced audio: intro→loop patterns, dynamic parameters, and stem mixing. ElysMusicEngine supports them natively — UMetaSoundSource inherits from USoundBase.

Setup

  1. Content Browser → Right-click → Sounds → MetaSound Source
  2. Name it (e.g., MSS_CombatMusic)
  3. Build your audio graph
  4. Push it like any other sound:
Push Music Layer
├─ Music: MSS_CombatMusic // MetaSound works!
└─ ...other settings

Real-Time Parameters

Control MetaSound parameters from Blueprint while music plays:

// Float parameter (e.g., intensity based on health)
Set MetaSound Parameter
├─ Layer Name: "Combat"
├─ Parameter: "Intensity"
└─ Value: 0.8

// Bool parameter (e.g., toggle phase)
Set MetaSound Bool
├─ Layer Name: "BossFight"
├─ Parameter: "IsPhase2"
└─ Value: true

// Trigger (e.g., force transition)
Trigger MetaSound Event
├─ Layer Name: "BossFight"
└─ Trigger: "TransitionNow"

Common Parameter Patterns

TypeParameterUse for
FloatIntensity (0-1)Mix between calm/intense stems
FloatFilterCutoffDynamic EQ
BoolIsPhase2Toggle boss phase
BoolPlayerLowHealthTrigger danger layer
TriggerHitOne-shot stinger in MetaSound
TriggerVictoryVictory flourish

Intro → Loop Pattern

Build a MetaSound that plays an intro once, then loops:

MetaSound Graph:
[Wave Player: "Intro" (Play Once)]
→ [On Finished] → Trigger
→ [Wave Player: "Loop" (Looping)]
→ [Output]

Push with FadeIn: 0.0 — the intro handles the transition.

Stem Mixing

Use Float parameters to mix multiple stems dynamically (like Hi-Fi Rush):

// Drums always at 100%
Set MetaSound Parameter ("Music", "Drums", 1.0)

// Bass fades in during combat
Set MetaSound Parameter ("Music", "Bass", 0.8)

// Melody only during boss phase
Set MetaSound Parameter ("Music", "Melody", IsPhase2 ? 1.0 : 0.0)

Quartz Beat Synchronization

Quartz is UE5's sample-accurate timing system. It ensures music transitions happen exactly on beat — no more awkward cuts mid-measure.

How It Works

Without Quartz:  [CUT] → [START]   Awkward
With Quartz: ♪ ♪ ♪ ♪ | → | ♪ ♪ ♪ ♪ On beat (aligned)

The clock is auto-created at 120 BPM, 4/4 time. No setup needed.

Quantized Transitions

All Push/Pop functions now support an optional Quantization parameter for beat-synchronized transitions:

// Immediate (no quantization)
Push Music Layer
├─ Layer: "Combat"
└─ Quantization: None

// Beat-synced
Push Music Layer
├─ Layer: "Combat"
└─ Quantization: Bar // Wait for next bar

Pop Music Layer
├─ Layer: "Combat"
└─ Quantization: Bar

This works with all layer functions:

  • Push Music Layer / Pop Music Layer
  • Push Music Layer By Tag / Pop Music Layer By Tag
  • Push Music Preset / Pop Music Preset
  • Push Music Preset By Tag / Pop Music Preset By Tag

Quantization Options

OptionWaits forBest for
NoneNothing (immediate)Sound effects
BeatNext beat (1/4 note)Quick transitions
HalfBarNext half bar (2 beats)Medium transitions
BarNext full bar (4 beats)Music changes
TwoBars2 full bars (8 beats)Dramatic moments

Clock Control

// Change tempo
Set Music BPM (140.0)

// Change time signature
Initialize Quartz Clock
├─ BPM: 120
└─ Beats Per Bar: 3 // 3/4 waltz time

Beat Events

React to beats in gameplay — VFX pulses, UI flashes, rhythm mechanics:

// Bind to beat event
Bind Event to On Beat

On Beat (BeatIndex, BarIndex, BPM)

// Flash screen on beat 1
Branch (BeatIndex == 1)
→ Spawn Flash VFX

Rhythm Gameplay Example

// Player attacks — check if on beat
Event OnPlayerAttack

Get Time Until Next Beat

Branch (Time < 0.2 seconds)
├─ True → Damage × 1.5 ("Perfect!")
└─ False → Normal damage

GameplayTag Integration

Drive music with GameplayTags for clean, scalable systems — especially useful with GAS (Gameplay Ability System).

Setup: Tag Registry

  1. Content Browser → Right-click → Data AssetMusicLayerRegistry
  2. Name it DA_MusicLayerRegistry
  3. Map tags to layers:
Tag: "Music.Exploration"
→ Music: Exploration_Theme
→ Priority: 0
→ Mode: Replace

Tag: "Music.Combat"
→ Music: Combat_Theme
→ Priority: 10
→ Mode: Replace

Tag: "Music.Combat.Boss"
→ Music: Boss_Theme
→ Priority: 15
→ Mode: Replace

Load the Registry

Add your registry to Project Settings → Plugins → Elys Music Engine → Layer Tag Registries, or load manually:

Event BeginPlay

Load Tag Registry
├─ Registry: DA_MusicLayerRegistry
└─ Clear Existing: false

Push/Pop by Tag

// Start combat music
Push Music Layer By Tag
└─ Tag: "Music.Combat"

// End combat
Pop Music Layer By Tag
└─ Tag: "Music.Combat"

Smart Parent Fallback

If Music.Combat.Boss.Phase2 isn't in the registry, the system automatically tries:

  1. Music.Combat.Boss.Phase2 ← not found
  2. Music.Combat.Boss ← not found
  3. Music.Combatfound! Uses this.

This lets you define broad tags and override specific ones as needed.

GAS Integration Example

In your Gameplay Ability:

// Ability activates → push combat music
Event OnAbilityActivated

Push Music Layer By Tag ("Music.Combat")

// Ability ends → pop
Event OnAbilityEnded

Pop Music Layer By Tag ("Music.Combat")

Next Steps