MetaSounds in UE5: One-Shot and Loop Patches for Game Audio

TLDR

Almost every game audio asset is either a one-shot (plays once, stops) or a loop (runs until stopped). MetaSound Patches let you build one reusable graph for each type and drop it into as many assets as you need. This post covers the structure of each patch, three to four practical use cases, and how they combine for layered sound design. All examples come from Shattered Realms, where this workflow handles everything from elemental ability variants to distance-based ambient layering.


I'd started exploring MetaSound patches before Shattered Realms got underway, but I didn't really understand why they mattered until I was deep into the implementation stage. The asset list kept growing each week, and I noticed something that should have been obvious sooner: a huge number of these sounds needed the same technical setup. Multiple types of abilities, music assets, and voice lines, all sharing the same underlying structure. Patches were the answer to that, and they're what made it possible to scale the audio system without ending up with graphs I'd have to untangle every time something needed changing.

This post walks through the two patches that handle almost every audio asset in Shattered Realms, one-shots and loops, along with the use cases each one shows up in.


Every Sound Is a One-Shot or a Loop

When I mapped out the full asset list for Shattered Realms, the obvious organizing principle was category. Player, enemy, ambience, music, UI. That works as a first pass, but it doesn't tell you anything about implementation. A footstep and a UI click look identical at the engine level. So does a torch and an ambient wind bed.

The more useful split is mechanical:

One-shots: sounds that play once and stop. Footsteps, impacts, UI clicks, ability activations, anything with a defined beginning and end.

Loops: sounds that run continuously until told to stop. Ambient beds, sustained effects, anything that persists and evolves over time.

Almost every sound in your game is one of these two. The question is how to build them in a way that scales when the asset list doubles. That's what patches are for.


A Quick Tour of the MetaSound Graph

Before getting into patches, a short orientation for anyone who hasn't spent much time inside a MetaSound Source yet.

INPUT On Play WAVE PLAYER (STEREO) Play Out Left Out Right INPUT On Play RANDOM (FLOAT) Next On Next Value WAVE PLAYER (STEREO) Play Out Left Pitch Shift Out Right STEREO MIXER (2) In 0 L Out L In 0 R Out R Gain 0 (Lin) In 1 L In 1 R Gain 1 (Lin) INPUT Cutoff Freq ADSR ENVELOPE (FLOAT) Trigger Attack On Done Trigger Release Out Envelope LADDER FILTER In Out Cutoff Freq LADDER FILTER In Out Cutoff Freq OUTPUT Out L OUTPUT Out R INPUT On Play INPUT On Finished OUTPUT On Finished Trigger Audio Float Cutoff Freq
Scroll to zoom · Drag to pan · Pinch to zoom on mobile

A complete MetaSound Source graph: two Wave Players mixed and shaped by an ADSR envelope, each channel filtered by a shared Ladder Filter. Hover over any node to see what it does.

When you open a MetaSound Source, the graph has an input, an output, and an OnFinished node. Signal flows left to right, like other visual scripting in UE. The graph above is a typical stereo one-shot: two Wave Players, one with pitch randomization, mixed together and run through a low-pass filter before output.

The nodes I come back to constantly:

  • Wave Player: plays back any audio asset, mono or stereo. Pitch, start time, and looping behaviour are all exposed. On Shattered Realms it's the starting point for every one-shot and every loop.

  • Mixers: combine multiple signals into one. Anything you're layering goes through one.

  • Effects: filters, flangers, phasers, delays, and in recent versions, independent reverbs.

  • AD / ADSR Envelopes: attack, decay, sustain, release. Familiar if you've used a synth. Useful for shaping amplitude, pitch, or filter movement.

Individually, these are tools. In patches, they become a workflow.


What MetaSound Patches Actually Change

A patch is a self-contained graph you drop into other graphs as a single node, or a function in code terms. You define inputs and outputs, build the logic inside, and reuse it anywhere. This is the feature that turned MetaSounds from an audio tool into something I'd call a proper audio programming system.

Four things change once you're working in patches:

Reusability. Build the logic once, use it across every graph that needs it. The one-shot patch I use for footsteps is the same one driving impacts, UI clicks, and ability triggers. The assets and parameters change; the structure doesn't.

Abstraction. The graph using the patch doesn't need to know what's inside it. You can swap a node, adjust an envelope, or add an effect to the patch internally, and nothing downstream breaks. The interface stays the same.

Consistency. Any change propagates everywhere the patch is used. If you decide all one-shots in the game need pitch variation, you add it once. No hunting through individual assets.

Composability. Patches can sit inside other patches. A one-shot patch lives inside a layering patch, which lives inside a full ability sound graph. You build complexity from simple, tested pieces.

One real gotcha: don't get carried away nesting patches. Each layer of nesting adds cost. I hit noticeable CPU spikes when I was testing generative music systems with dense nesting. If you want to see what that looks like in practice, I cover the full system in Building Dynamic Music Systems in UE5. For everyday one-shot and loop work it's fine, but use nesting deliberately rather than by reflex.

Once you're thinking in patches, the way you plan and categorize your asset list changes too. The two patches that cover almost everything are one-shots and loops.


Building a Reusable One-Shot Patch

Here's the structure I use. It's built around one trigger and a defined end.

INPUT Play INPUT In Array INPUT No Repeats RANDOM GET (ARRAY) Next On Next In Array Value No Repeats RANDOM (FLOAT) Next On Next Min Value Max INPUT Pitch Min INPUT Pitch Max WAVE PLAYER (STEREO) Play On Finished Wave Asset Out Left Pitch Shift Out Right OUTPUT On Finished OUTPUT Out Left OUTPUT Out Right Trigger Audio Float Array / Asset
Scroll to zoom · Drag to pan · Pinch to zoom on mobile

The reusable one-shot patch: Random Get selects a wave asset from the input array, Random Float generates the pitch offset, and Wave Player handles stereo playback. Hover over any node to see what it does.

  • An On Play input trigger to start the graph

  • One or more Wave Players for playback

  • An Asset Array input containing the assets to choose from

  • A Get Random Asset from Array node

  • A Random Float node for pitch variation on every trigger

  • An Audio Output at the end of the chain

The audio assets are inputs to the patch, not baked in. That's what makes it reusable. The parent graph supplies the assets, the patch handles playback. Resist the urge to load the patch up with extra responsibilities. A patch that does too much becomes the first thing you dread opening. Keep it focused on core playback and let the parent graph handle contextual treatment.

1. Dropping the Patch Into a New Graph

INPUT On Play INPUT In Array ONE SHOT ASSET RANDOMIZER Play On Finished In Array Out Left Out Right OUTPUT On Finished OUTPUT Out Left OUTPUT Out Right Trigger Audio Array / Asset
Scroll to zoom · Drag to pan · Pinch to zoom on mobile

The One Shot Asset Randomizer patch dropped into a new MetaSound Source graph as a single node. On Play and an asset array wire in on the left; On Finished and stereo audio wire out on the right. Hover over any node to see what it does.

The first use case is the simplest: open a new MetaSound Source, right-click, search for your patch, and drop it in as a single node. Wire On Play, an asset array, and the output, and you have a working one-shot built from one node instead of five.

The friction this removes is the same five-node setup you'd otherwise rebuild every time. On a project with hundreds of one-shots, the time savings add up fast. The bigger payoff, though, is mental. You stop thinking about plumbing and start thinking about the sound.

2. Adding Effects or Envelopes in the Parent Graph

Because a patch is just a node, you can keep processing its output downstream. Add a pitch envelope for a frequency sweep. Run it through a filter with a cutoff driven by a gameplay parameter. The patch handles core playback; the parent graph handles whatever this specific asset needs to do.

3. Layering Multiple One-Shot Patches Together

This is where the system pays off. Instead of building a complex layered sound from scratch every time, stack one-shot patches in a single graph and mix their outputs.

A real example from Shattered Realms: the warp ability. Each elemental variant (fire, ice, wind, lightning) is built from several one-shot patches running in parallel, each handling a different layer of the sound: body, transient, tail. The elemental character comes from swapping asset inputs and tweaking parameters on each patch. The underlying structure stays identical across all four variants. Adding a fifth would mean wiring in new assets, not rebuilding the architecture.

MetaSound: Whoosh Randomizer
INPUT On Play INPUT High Whoosh ONE SHOT ASSET RANDOMIZER Play In Array Out Left Out Right INPUT On Play INPUT Low Whoosh ONE SHOT ASSET RANDOMIZER Play In Array Out Left Out Right STEREO MIXER (3) In 0 L In 0 R In 1 L In 1 R In 2 L In 2 R Out L Out R OUTPUT Out Left OUTPUT Out Right INPUT On Play INPUT Tail ONE SHOT ASSET RANDOMIZER Play In Array On Finished Out Left Out Right OUTPUT On Finished
Scroll to zoom · Drag to pan · Pinch to zoom on mobile
Trigger Audio Wave Array

Three One Shot Asset Randomizer patches running in parallel, each handling a separate layer of the sound: high whoosh, low whoosh, and tail. All three feed into a Stereo Mixer (3), with the tail patch also exposing On Finished to signal when the sound completes. Hover over any node to see what it does.


Building a Reusable Loop Patch

A loop patch is for sustaining sounds: looping wave assets, sequences, or fully procedural loops. This post focuses on looping wave assets; sequences and procedural setups deserve their own post.

Here's the structure:

MetaSound: Wave Player + Random Pitch + LFO
INPUT Pitch Max INPUT Pitch Min INPUT Input INPUT Random LFO Rate INPUT LFO Min Value INPUT LFO Max Value MSP_RANDOMPITCH Max Min Rand Pitch Trig On Trigger Pitch out LOW FREQUENCY NOISE Rate Min Value Max Value Out INPUT Stop INPUT Wave Asset ADD A B Sum INPUT Loop INPUT Start Time WAVE PLAYER (STEREO) Play Stop Wave Asset Pitch Shift Loop Start Time On Play On Finished On Looped Out Left Out Right OUTPUT On Play OUTPUT On Finished OUTPUT On Looped OUTPUT Out Left OUTPUT Out Right
Scroll to zoom · Drag to pan · Pinch to zoom on mobile
Trigger Float Audio Wave Asset Boolean

The reusable loop patch: MSP_RandomPitch generates a stepped random pitch on each trigger while Low Frequency Noise adds continuous slow drift. Both feed into an Add node whose Sum drives the Wave Player's Pitch Shift input. Stop, Wave Asset, Loop, and Start Time are all exposed as patch inputs. Hover over any node to see what it does.

A single Wave Player holds the looping asset. Pitch variation comes from two sources combined: an MSP_RandomPitch that fires a new value on each trigger (stepped), and a Low Frequency Noise that runs continuously (smooth). Summing them gives a fresh random offset each cycle, with slow organic drift on top.

The Low Frequency Noise exposes three inputs:

  • Random LFO Rate: how fast the pitch drifts. Higher values produce a faster wobble; lower values give a slow, barely perceptible drift.

  • LFO Min Value: the lowest semitone offset the drift can reach.

  • LFO Max Value: the highest semitone offset the drift can reach.

A few other inputs and outputs worth exposing:

  • A custom Stop input for clean shutdown.

  • A Loop boolean as an input rather than hardcoded, so you can preview the asset as a one-shot and switch to looping at runtime.

  • A Start Time input that sets where in the sample playback begins. You can later wire this to a random float so the loop starts from a different point each time it plays.

  • Loop Start and Loop Duration to define the loop region inside the sample, useful when an asset has a distinct intro before the loop body.

  • On Play, On Looped, and On Finished outputs. On Looped fires every cycle; On Finished only fires when playback fully stops, either because Loop is false or the sound was cut.

The thing that separates a well-built loop patch from one that causes problems downstream is how it handles the stop condition. Get that right and the use cases below become straightforward.

1. Dropping the Patch Into a New Graph

Same principle as the one-shot version: drop the loop patch in, wire different assets and parameters to its inputs, connect the output.

MetaSound: MSP_LoopStereoSound
INPUT On Play INPUT LFO Max Value INPUT LFO Min Value INPUT Random LFO Rate INPUT Stop INPUT On Play INPUT Wave Asset GET WAVE DURATION Wave Duration RANDOM (TIME) Next Max Value MSP_LOOPSTEREOSOUND Input LFO Max Value LFO Min Value Random LFO Rate Start Time Wave Asset Stop On Finished Out Left Out Right OUTPUT On Finished OUTPUT Out Left OUTPUT Out Right
Scroll to zoom · Drag to pan · Pinch to zoom on mobile
Trigger Float Audio Wave / Array

The MSP_LoopStereoSound patch dropped into a new MetaSound Source graph. On Play, LFO parameters, Stop, and Wave Asset wire in from the left. Get Wave Duration reads the file length and feeds it into Random(Time), which picks a random start position on each play event. On Finished, Out Left, and Out Right come out on the right. Hover over any node to see what it does.

When using loops, an abrupt stop rarely sounds intentional. Usually you need a fade out before On Finished fires. The cleanest approach depends on context. You can handle it inside the patch, where an ADSR with exposable fade times bakes the fade into patch logic, or externally in Blueprint or C++, which is useful when gameplay systems are already managing state. My preference is to add the ADSR in the parent Source graph rather than the patch, because different loop types need genuinely different stop behaviour. A music loop needs a crossfade. A torch might need an instant cut followed by an extinguish sound. An ambient bed might fade with a filter cutoff sweep instead of a volume fade. Keeping the patch simple and handling the contextual stop in the Source graph preserves that flexibility.

2. LFO Modulation on Pitch or Volume

Loops are where modulation gets interesting. Inside the patch, or applied to its output in the parent graph, driving an LFO into pitch or volume introduces organic movement. Modulating pitch on the Wave Player behaves like tape vari-speed: pitch and timing shift together, which is useful for charging abilities that need variation. Modulating volume makes an ambient wind loop feel alive rather than mechanical.

3. Staged Loops

This pattern is for sounds with distinct intro, sustain, and outro phases. Common for abilities with active and inactive states, or any sound that needs to feel like it has a beginning, a middle, and a deliberate end.

The structure is a three-stage sequence: a one-shot fires on start, a loop fades in and sustains until the Stop parameter triggers, then a fade out plays followed by a final one-shot to signal completion. Each stage is its own patch, so each can be swapped or adjusted independently without touching the others.

MetaSound: Outer Loop System
INPUT INPUT On Play INPUT INPUT Stop INPUT ONE SHOT ASSET RANDOMIZER Play In Array Out Left Out Right MSP_LOOPSTEREOSOUND Input Stop Wave Asset Out Left Out Right ADSR ENVELOPE (FLOAT) Trigger Attack Trigger Release Out Envelope ONE SHOT ASSET RANDOMIZER Play In Array On Finished Out Left Out Right STEREO MIXER (3) In 0 L In 0 R In 1 L In 1 R Gain 1 (Lin) In 2 L In 2 R Out L Out R OUTPUT Out Left OUTPUT Out Right OUTPUT On Finished
Scroll to zoom · Drag to pan · Pinch to zoom on mobile
Trigger Float Audio Wave Array

The staged loop system: On Play triggers an intro one-shot and starts MSP_LoopStereoSound with an ADSR fade-in. Stop releases the ADSR, cuts the loop, and fires an outro one-shot. All three layers feed into a Stereo Mixer (3), with the loop's gain driven by the ADSR envelope on channel 1. The outro's On Finished output signals the sound is fully complete. Hover over any node to see what it does.

4. Layered Loops

The same layering principle from one-shots applies here, with more nuance. For a waterfall, you might have separate loops for different distances: a detailed, splashy texture up close, and a softer low rumble heard from far. Each loop runs through its own MSP_LoopStereoSound instance, with independent pitch randomisation and LFO modulation.

Instead of crossfading by adjusting volume on each layer, this graph uses a pair of Crossfade (Audio, 2) nodes, one for left and one for right. Each crossfade takes both versions of its channel (close on In 0, distant on In 1) and blends between them using a single float. That float comes from an Input Distance node connected to Unreal's built-in attenuation system. As the player moves away from the waterfall emitter, the close loop fades down while the distant loop fades up in its place.

MetaSound: Waterfall Crossfade
INPUT Distance (UE.Attenuation) INPUT On Play MSP_LOOPSTEREOSOUND Input Wave Asset Out Left Out Right INPUT INPUT On Play MSP_LOOPSTEREOSOUND Input Wave Asset Out Left Out Right INPUT CROSSFADE (AUDIO, 2) Crossfade Value In 0 In 1 Out CROSSFADE (AUDIO, 2) Crossfade Value In 0 In 1 Out OUTPUT Out Left OUTPUT Out Right
Scroll to zoom · Drag to pan · Pinch to zoom on mobile
Trigger Float Audio Wave Array

Two MSP_LoopStereoSound patches run in parallel, one for the close waterfall and one for the distant version. Their stereo outputs feed into a pair of Crossfade (Audio, 2) nodes, one per channel. Distance from Unreal's attenuation system drives the blend: as the player moves away, the close loop fades down and the distant loop fades up in its place. Hover over any node to see what it does.


Summary

The realization that pushed me toward this workflow was simple in hindsight. Multiple types of abilities, music assets, and voice lines all need the same technical treatment. Once that clicked in the implementation stage, patches stopped feeling like a power-user feature and started feeling like the only sensible way to organize the audio. The result is a project where adding new variants is assembly rather than construction, and where the graphs stay readable instead of accumulating into something only I can navigate.

The patterns above cover the majority of what a game needs, but there's more to explore. Sequences, procedural loops, and generative music systems are all possible inside MetaSounds and worth a post of their own. More on that soon.


FAQ

Should every sound be a one-shot or a loop? Yes, in terms of the underlying patch. The categorization is mechanical, not aesthetic. A musical sting that plays once is a one-shot. A drone that runs for thirty seconds is a loop. Whether it sits in an ability, a UI, or an ambient bed doesn't change which patch handles it.

Is there a performance ceiling on patch nesting? I haven't pushed it to a hard number, but I hit noticeable CPU spikes when I was testing generative music systems with dense nesting, multiple patches inside patches inside patches. For most one-shot and loop work, one or two levels of nesting is fine. Past that, profile before you commit.

Can I share patches across projects? Yes, MetaSound patches are assets like any other. Move them into a shared content folder, or migrate them between projects with the standard Unreal asset migration tools. Building a reusable patch library is one of the bigger wins of working this way.

Do patches help with procedural or generative music? Yes, but it's worth treating that as a separate problem from one-shots and loops. Generative systems tend to involve sequencing, conditional logic, and tempo-aware events, which warrant their own patch architecture. That's a topic for a future post.

What happens if I change a patch that's used in twenty graphs? All twenty graphs pick up the change. That's the upside of consistency and the risk of it. Test changes to widely-used patches the same way you'd test a function used across a codebase.

Next
Next

MetaSounds in UE5: The Case for Ditching Middleware