The first version of the graph sounded right in a solo audition. Six heal takes, a random node choosing one, a short envelope, a little pitch drift. Then four players healed inside the same second of a co-op test and the cue turned into a burst of clicks. The random node was re-rolling on every audio block instead of once per trigger, and the wave player was being restarted by a graph that never stopped running.
That is a graph design failure, not a mixing failure. A heal cue in MetaSounds is a handful of nodes doing different jobs, and each one has its own way of going wrong. Building it node by node is also what makes reuse work later, because a graph honest about its inputs can carry a small heal, a large heal and a party heal without a second asset.
One Wave Player, One Array, One Trigger
Start with the material. Six takes of the same heal, 240 to 320 ms each, trimmed to start on the first non-zero sample and exported as 48 kHz 16-bit WAV. Variation lives in the array, so the takes should differ in things a player can hear: the attack noise, the exact decay, a small difference in the final pitch. If the six files are six copies of one render, the random node has nothing to select.
A Make Array node holds the six Sound Waves. Feed it into the array Get node and drive the index with a Random node set to integer output, ranged 0 to 5 so it stays inside the buffer. The Get output goes to the Wave Asset pin of a Wave Player, which takes one more input: Play. Wire the On Play event through a Trigger node into that pin, and leave Loop off.
The array is the variation budget
Six takes is a sensible starting number. The ear starts noticing a pattern around the fourth or fifth repetition of a short cue, so a pool of five to eight usually covers a fight without audible cycling, and it keeps the Sound asset small. More takes do not fix a badly shaped cue; they only hide the repetition for one more encounter.
The Envelope Shapes the Heal, the Wave Provides the Body
Put the amplitude shape in the graph, not in the file. An AD Envelope node with Attack around 6 to 10 ms and Decay around 150 to 220 ms, multiplied into the Wave Player output through a Multiply node, gives a heal you can retime per call. If the shape is baked into the WAV, every retime is a re-render and a re-import.
Keep the attack short. A 25 ms fade-in reads as a swell rather than a pickup, and at that point the cue describes a potion being poured instead of health arriving. The decay should curve downward rather than fall in a straight line; a linear 200 ms ramp sounds like someone pulling a fader down by hand.
The envelope is also the first place an intensity value can act. Wire that value into a Lerp node between 120 ms and 260 ms and feed the result into the Decay input. A small heal closes in roughly 120 ms and a party heal takes about twice as long, which is enough for the two events to feel like different sizes while using the same six waves.
Pitch Randomness Has to Be Bipolar and Bounded
A one-directional pitch offset is one of the quiet causes of a heal cue that drifts sharp over a long fight. A random range from 0 to 40 cents moves the average pitch up by 20 cents, so the cue slowly separates from the recorded material and from everything else in the palette. Use a Random Float from -0.35 to +0.35 semitones, roughly plus or minus 35 cents, and the average stays where the take was recorded.
A full semitone is usually too much for a heal. At that size the cue starts to sound like a different note rather than the same event played again, and in a dense mix it reads as unstable pitch.
If the variation should scale with intensity, multiply the random output by a Lerp between 0.2 and 1.0 before it reaches the Pitch pin, which is in semitones. Small heals then move by about 7 cents and a party heal gets the full spread.
One Intensity Pin Covers Small, Large and Party Heals
Declare a single Float graph parameter named Intensity, ranged 0 to 1, and read it with a Get node. Three destinations cover most heal cues: the envelope decay, the pitch spread, and a Gain node. A State Variable Filter is the fourth, with cutoff lerped from about 1.2 kHz at 0 to 5 kHz at 1.
The mapping does not have to be linear. A small heal at 0.2 should still sound finished, not like a quieter party heal, so the decay lands near 130 ms, gain sits at -3 dB and the filter stays partly closed. At 1.0 the decay opens to 260 ms, gain returns to unity and the filter opens. Three heal tiers then share one graph, one set of takes and one place to fix a bug.
Setting the value from Blueprint
Set the value before the trigger. On the Audio Component, call Set Float Parameter with the name Intensity and the tier value, then call Execute Trigger Parameter on the same component. If the MetaSound Source is set to Auto Activate, the graph starts before the first parameter arrives and the first heal of a session plays at the default value. A small data asset that maps heal tiers to intensity values keeps the Blueprint readable and lets design tune the numbers without opening the graph.
Why the Random Node Re-rolls, and Where the Graph Gets Expensive
MetaSounds evaluates audio in blocks, 48 samples by default, which is about 1 ms at 48 kHz. A node that is not gated by a trigger can be re-evaluated on every block. That was the failure from the opening: the Random node feeding the index sat on a path that kept executing, so the take changed hundreds of times a second while the Wave Player restarted.
Gate the random on the same trigger that starts the wave. When the Random node sits downstream of the Trigger node it evaluates once per event, which is the behaviour you want. It is also the core idea behind controlled randomness : variation tied to events sounds designed, variation tied to the clock sounds like noise.
Cost stacks in a predictable order: every active Wave Player is a voice, so polyphony is the first bill. Per-sample work such as a filter costs more than a block-rate Random or Lerp. One wave player with six takes is cheaper than six players, and one parameterised graph reused three times is cheaper than three graphs with their own waves. Concurrency settings on the Sound asset decide whether twenty pickups in a boss fight stay flat or multiply.
If the project has not settled on MetaSounds yet, that decision changes how much of this graph you have to own, and choosing between MetaSounds and middleware is worth doing before the graph grows. The broader set of node patterns is covered in procedural MetaSounds .
A Testing Routine That Runs Inside the Editor
Audition the graph in the MetaSounds editor with the parameter panel open. Set Intensity to 0 and trigger twenty times. Listen for whether any take repeats obviously, and whether the pitch drift has a direction. Then set Intensity to 1 and repeat; the party heal should last longer and sit louder without the attack changing character.
Bypass the envelope and listen to the raw wave player. If the takes already fade in slowly, the graph envelope is stacking on top and the attack will never be sharp. Then solo the first 40 ms and check that it still reads as something positive.
- Twenty triggers at 0.2. The cue should sound the same kind of event every time, with no take standing out as the odd one.
- Over a combat bed. Play the graph against a looping mix instead of solo, because a cue that survives alone can disappear under gunfire.
Watch the active voice count while triggering, and when it reaches the dozens capture an Audio Insights session or open stat audio in a packaged build. Voices and graph cost per voice together tell you whether the reuse saves anything.
The last check is the one that decides whether the graph ships: trigger ten heals in a row at 0.2 and confirm none of them sounds broken. Reuse fails quietly. A graph that covers three heal sizes is only worth the complexity if all three still sound intentional.