Audio
Four destruction audio events, deterministic weighted variation, built-in playback and middleware-neutral request delegates with their own frame budget.
The four events
ESDFAudioEvent:
| Event | Emitted when |
|---|---|
LightImpact | A valid hit below the profile’s heavy thresholds |
HeavyImpact | A hit at or above HeavyImpactMinimumPower or HeavyImpactMinimumImpulse |
Break | The object is destroyed |
DebrisImpact | A spawned debris piece collides fast enough |
Weighted variations
Each event reads an array of FSDFWeightedSound from the profile:
| Property | Default | Meaning |
|---|---|---|
Sound | none | Soft USoundBase reference |
Weight | 1.0 | Relative selection weight |
MinimumVolume | 0.9 | Lower bound of the volume multiplier |
MaximumVolume | 1.0 | Upper bound |
MinimumPitch | 0.95 | Lower bound of the pitch multiplier |
MaximumPitch | 1.05 | Upper bound |
Empty entries and zero-weight entries are ignored safely — an incomplete array never crashes and never plays silence.
SoundBase is the accepted type, so Sound Waves, Sound Cues and MetaSound sources all work. The
profile can also carry an optional SoundAttenuation and SoundConcurrency asset applied to
built-in playback.
Shipped break cues
The runtime profile templates generated by the authoring presets come with a break sound already assigned, from the plugin’s own demo audio:
| Preset family | Break cue |
|---|---|
| Wood, Wooden Crate, Wooden Furniture, Wooden Coffin | SC_SDF_WoodenCrate_Break |
| Wooden Barrel (Semantic) | SC_SDF_WoodenBarrel_Break |
| Ceramic | SC_SDF_CeramicImpact |
| Stone | SC_SDF_StoneImpact |
| Glass, Glass Vessel | SC_SDF_GlassBreak |
| Generic | none — a neutral preset assumes no material |
These are starting points on the generated profile, not hard-wired behaviour: replace them on your own profiles or preset templates like any other weighted variation.
Deterministic selection
SelectWeightedSoundVariation(Variations, RandomSeed, OutVolumeMultiplier, OutPitchMultiplier) is a
pure, static, Blueprint-callable function. The same seed always selects the same variation with the
same volume and pitch multipliers.
The framework uses it internally, and it is exposed so a middleware layer or a test can reproduce the exact selection the framework would have made.
Built-in playback versus delegates
Two independent switches on the profile:
| Property | Effect |
|---|---|
bEnableAudioRequests | Master switch: emit audio requests at all |
bEnableBuiltInAudioPlayback | Also play the selected sound through UGameplayStatics |
Requests are always emitted
Disabling built-in playback does not disable the requests. The delegates still fire with a fully resolved selection, which is exactly what a middleware integration needs.
The request payload
FSDFDestructionAudioRequest:
| Field | Meaning |
|---|---|
Event | Which of the four events |
SourceActor | The destructible |
Location | World position |
ImpactDirection | Direction of the causing hit |
ImpactSpeed | Speed associated with the event |
DestructionPower | Power of the causing hit |
SelectedSound | The variation the framework picked |
VolumeMultiplier | Resolved volume multiplier |
PitchMultiplier | Resolved pitch multiplier |
RandomSeed | Seed used for the selection |
SelectedVariationIndex | Index into the profile array |
bBuiltInPlaybackRequested | Built-in playback was configured |
bBuiltInPlaybackAttempted | Built-in playback was actually attempted |
bBuiltInPlaybackSuppressedByBudget | The per-frame built-in audio budget suppressed it |
Where to listen
| Scope | Delegate |
|---|---|
| One object | USDFDestructibleComponent::OnDestructionAudioRequested |
| Whole world | USDFDestructionSubsystem::OnDestructionAudioRequested |
The component delegate fires before built-in playback is attempted, which makes it a genuine interception point. The subsystem delegate is the right hook for a global router — MetaSounds, Wwise, FMOD or your own pooled audio system.
Middleware integration pattern
- Set
bEnableAudioRequests = trueandbEnableBuiltInAudioPlayback = falseon your profiles. - Bind
USDFDestructionSubsystem::OnDestructionAudioRequestedonce, at world start. - Map
Event,DestructionPowerand any gameplay tags from the causing hit to your own event names. - Post the event at
Location, applyingVolumeMultiplierandPitchMultiplierif you want the framework’s variation, or ignoring them and using your middleware’s own randomisation.
You can also leave the Sound arrays empty in that setup: the request is still emitted with
SelectedVariationIndex = -1, which your router can treat as “no asset, use my own mapping”.
Debris impact audio
Debris collisions are throttled by three profile properties so a shattering pot does not produce thirty simultaneous clacks:
MinimumDebrisImpactSpeed— slower collisions are silent;DebrisImpactCooldown— minimum seconds between debris sounds;MaximumDebrisImpactSoundsPerDebrisActor— hard cap per piece, default1.
Audio budget
The world subsystem caps MaxBuiltInAudioEventsPerFrame (default 32). The cap applies only to
built-in playback attempts. Requests always reach the delegates, so a middleware integration is never
silently starved by the framework’s own budget.
Diagnostics through GetAudioStats return FSDFDestructionAudioStats:
| Field | Meaning |
|---|---|
TotalRequests | Requests emitted since the last reset |
TotalBuiltInPlaybackAttempts | Built-in playbacks attempted |
TotalBuiltInPlaybackSuppressed | Built-in playbacks suppressed by the budget |
BuiltInPlaybackAttemptsThisFrame | Current frame counter |
GetLastAudioRequest returns the most recent payload and ResetAudioStatistics clears the counters
without touching active state.
Last updated: 2026-08-25