In a large game, keeping every zone’s audio in memory wastes RAM on sounds the player can’t hear. Pepper.SFX can load a zone’s clips through Unity’s Addressables when the listener walks in and release them when it leaves, without unloading a clip a voice is still playing.
How it works
- The clip-source layer. Containers ask the active clip source for each clip. By default it returns the clip you assigned; the Addressables backend swaps in one that loads by address. Each entry holds a direct clip or an address, never both. Random, Sequence and Routing container entries and Ambient Source loops can be addressable.
- The warmer.
WarmContainer,WarmClipandWarmClipson the Audio Manager load the audio data of directly referenced clips before their first play, so it doesn’t hitch. No extra package needed. - Banks per zone. A bank is an Addressables label, named by a Zone Audio Bank component on an Audio Zone. The bank preloads when the listener enters and is released after a linger (5 s by default) when it leaves, so a border doesn’t cause churn.
- Nothing unloads under a playing voice. A clip stays loaded while a bank, a playing voice or a pin holds it. A loop started in one zone plays on in the next, keeping only its own clip loaded.
- Zones really unload. Proved in a Windows player build with three zones: standing in one held 7.4–11.3 MB of audio against 26.1 MB for all three, 57–72% less.
- Addressable Audio Authoring window. Select containers, pick a Bank Label and Address Style, and click Convert to Addressable. Each bank gets its own group with one bundle per clip; Revert to Direct undoes it. The Groups tab marks clips used or unused, adds clips that aren’t in a container, and removes unused ones.
- Loading Validator window. Flags an address with no backend, a mistyped address, or an entry with both a clip and an address, even without Addressables installed.
Example
using AudioSystem;
using AudioSystem.Propagation;
using UnityEngine;
public class LevelAudioLoading : MonoBehaviour
{
[SerializeField] private AudioContainer bossMusic; // direct clips, not addressable
// Before the boss fight: load the music's audio data so its first play doesn't hitch.
public void OnBossDoorOpened()
{
AudioManager.Instance.WarmContainer(bossMusic);
}
// After moving the player in one jump (a respawn or fast travel):
// the zones left behind release their banks, and the zones landed in load theirs.
public void OnPlayerTeleported()
{
if (PropagationManager.HasInstance)
PropagationManager.Instance.ResyncListenerAfterTeleport();
}
}
Zone banks need no code. The example shows the two jobs that do: a jump in position, and warming direct clips.
Setting it up
- Install Addressables (
com.unity.addressables) from the Package Manager. Pepper’s backend compiles by itself. - Select a zone’s containers, open Window > Audio System > Addressable Audio Authoring, set a Bank Label, leave Group on Bank’s own group, and click Convert to Addressable.
- On the Audio Zone’s GameObject, Add Component > Audio > Loading > Zone Audio Bank, with the same Bank Label.
- In your first scene, Add Component > Audio > Loading > Addressable Audio Runtime. One is enough; it persists across scene loads.
- Run Window > Audio System > Loading Validator and click Validate.
- Check memory in a Development Build with Unity’s Memory Profiler.
Good to know
- The clip-source layer and the warmer are in every version. The Addressables backend, the Addressable Audio Authoring window and the Loading Validator are full version only.
- One group for every zone saves no memory: Unity unloads a bundle only as a whole. The Groups tab flags such a group and offers Pack Each Clip Separately.
- A clip that isn’t loaded yet is skipped, not played late. Keep a zone’s bank loaded before its sounds are needed.
- With the editor’s default Play Mode Script (Use Asset Database), clips never really unload: measure in a player build.
- A group left out of builds plays in the editor but not in a build. The Groups tab’s Include in Builds button fixes it.
- Banks follow Audio Zones, one label per zone. Events and containers still load up front; only clips load on demand.