The MMSoundManager, and the classes it works with, is a system that will let you play and control sounds over a number of tracks, using events. It’s built on top of Unity’s AudioMixer system, and will provide you with a simple interface to get full control over your game’s sounds. Of course it also comes with dedicated feedbacks to make it even easier to use. Note that because it’s built on top of Unity’s native systems, you don’t have to use it if you don’t want to, it’s optional, and it can also peacefully coexist next to other sound systems.
Its main features are :
- Play/stop/pause/resume/free sounds
- Full control : loop, volume, pitch, pan, spatial blend, bypasses, priority, reverb, doppler level, spread, rolloff mode, distance
- 2D & 3D spatial support
- Built-in pooling, automatically recycle a set of audio sources for maximum performance
- Built in audio mixer and groups, with ready-made tracks (Master, Music, SFX, UI), and options to play on more groups if needed
- Stop/pause/resume/free entire tracks
- Stop/pause/resume/free all sounds at once
- Mute / set volume entire tracks
- Save and load settings, with auto save / auto load mechanics built-in
- Fade in/out sounds
- Fade in/out tracks
- Solo mode : play a sound with one or all tracks muted, then unmute them automatically afterwards
- PlayOptions struct for clean API calls
- Option to have sounds persist across scene loads and from scene to scene
- Inspector controls for tracks (volume, mute, unmute, play, pause, stop, resume, free, number of sounds)
- retrocompatibility with older MM systems and events, like MMSfxEvents
- MMSoundManagerEvents : mute track, control track, save, load, reset, stop persistent sounds
Setting up MMSoundManager
The first thing you’ll need if you want to play sounds via the MMSoundManager will be to have one in your scene. Create a new, empty object, set it at the root of your scene’s hierarchy, and add a MMSoundManager component to it. Automatically, it’ll set a default Settings scriptable object to use (which you can keep, it’s fine), and you’ll see its signature 4 tracks controls.
The MMSoundManager uses tracks to play sounds on, to give you global control over each of them. Under the hood, these are regular AudioMixer Groups, piloted by the MMSoundManager. That means you can also play sounds on them directly, outside of the MMSoundManager, and they’ll still all play nicely with each other. The system is built around 3 base tracks : UI, SFX, Music, and a 4th Master track that controls all 3 others. These 3 tracks are usually enough for most games, but you can also use more if you’d like. When playing a sound, it’ll be important to play it on the right track.
The easiest way to interact with the MMSoundManager is via MMFeedbacks. The system ships with plenty of feedbacks for all common use cases, and will let you play a sound, control it, control entire tracks or all sounds at once.
The first feedback you’ll want to play with will likely be the MMSoundManager Sound. As you can guess, it lets you play a sound through the MMSoundManager system. From its (massive) inspector, you’ll be able to set the audio clip you want to play or a list of audioclips to pick from at random. Even outside of play mode, two convenient test buttons will let you check how it sounds. Then, you’ll be able to define a min/max volume and min/max pitch.
It’s SoundManager Options section lets you select the track to play the sound on, an ID (has to be unique, and will let you control that specific sound later on). There you can also force a specific audio group, or an audio source to recycle. In most cases, you can leave these blank, and the system will take care of that for you. You can have your sound loop (in which case it’ll start playing again once it reaches its end), or be persistent, meaning it’ll survive across scene loads. You can define a fade over a curve, and optionally pick a Solo mode.
In solo mode, a sound will mute other sounds while it’s playing. Solo Single Track will let you pick a track, and will mute it while that sound plays. Solo All Tracks will mute all other tracks. Checking Auto Unsolo at the end will have the system mute the tracks, play that sound, and unmute them automatically once it’s finished playing.
And then you’ll find plenty of other options (spatial settings, bypasses, distance) that are direct AudioSource controls. You can learn more about them in the AudioSource documentation.
MMSoundManager Sound Control
This feedback lets you control all sounds that match a specific ID. That ID is the same you specified in the feedback above. Usually you’ll want it to be unique per sound, but you can also have more than one sound matching the same ID, in which case they’ll all answer to the same commands.
The control feedback lets you :
- pause : pauses the sound with the specified ID, ready to be resumed.
- resume : plays the sound with the specified ID, resuming play if it had been paused, starting from the start if it had been stopped.
- stop : pauses the sound and moves the sound play head at the start of the file.
- free : stops a sound and returns the audio source it was playing on to the manager’s audio pool, ready to be used by the next sound to play. This helps save resources and improves performance. Use it once you know that sound won’t be needed again soon.
MMSoundManager Track Control
This feedback offers similar options (pause, resume, stop, free), but applied to an entire track (UI, SFX, Music, Master) instead of just a single sound.
The track control feedback lets you :
- pause : pauses all sounds playing on the specified track, ready to be resumed.
- resume : plays all sounds on the specified track, resuming play if it had been paused, starting from the start if it had been stopped.
- stop : pauses all sounds on the specified track, and moves their play head at the start of the file.
- free : stops all sounds on the track and returns their audio sources to the manager’s audio pool, ready to be used by the next sound to play. This helps save resources and improves performance. Use it once you know that sound won’t be needed again soon.
- set volume : sets the volume of the track to the specified value
- mute : sets the volume of all the sounds on the track to 0
- unmute : sets the volume of all the sounds on the track to whatever it was before they got muted
MMSoundManager All Sounds Control
Similar to the Sound Control and Track Control feedbacks, this one will let you control all sounds at once.
The All Sounds Control feedback lets you :
- pause : pauses all sounds, ready to be resumed.
- play : plays all sounds, resuming play if it had been paused, starting from the start if it had been stopped.
- stop : pauses all sounds, and moves their play head at the start of the file.
- free : stops all sounds and returns their audio sources to the manager’s audio pool, ready to be used by the next sound to play. This helps save resources and improves performance. Use it once you know that sound won’t be needed again soon.
- free all but persistent : frees all sounds in the scene, except the ones marked as persistent
- free all but looping : frees all sounds in the scene, except the ones marked as looping
MMSoundManager Sound Fade
This feedback will let you fade the volume of the sound with the specified ID towards a final volume, over the duration of your choice, and along the tween you’ve selected.
MMSoundManager Track Fade
This feedback will let you fade the volume of the specified track towards a final volume, over the duration of your choice, and along the tween you’ve selected.
MMSoundManager Save & load
This simple feedback will let you ask the MMSoundManager to save, load, or reset its settings. This saves to and loads from file, so it can persist across sessions.
Of course, you can do everything described above via code if you prefer to. You can either target your MMSoundManager directly, either via a reference, or via its singleton Instance (MMSoundManager.Instance.SomeMethod()), or use events, which would be the recommended way (reduces coupling, won’t throw errors if you don’t have a sound manager in your scene).
Here are most of the events that will let you control sounds :
This event will let you play a sound on the MMSoundManager
/// will play a clip (here ours is called ExplosionSfx) on the SFX track, at the position of the object calling it MMSoundManagerSoundPlayEvent.Trigger(ExplosionSfx, MMSoundManager.MMSoundManagerTracks.Sfx, this.transform.position);
The call above is a simple one, but you can also trigger the event and pass it a struct containing all advanced options possible, or just some of them :
// we create a new options struct MMSoundManagerPlayOptions options; // we initialize it with the default values options = MMSoundManagerPlayOptions.Default; // we override a few options options.Volume = 0.5f; options.Priority = 200; options.Loop = true; // we call our event, pass it our options, our sound plays MMSoundManagerSoundPlayEvent.Trigger(sfx, options);
An event used to control a specific sound on the MMSoundManager. You can either search for it by ID, or directly pass an audiosource if you have it.
/// will cause the sound(s) with an ID of 33 to stop playing MMSoundManagerSoundControlEvent.Trigger(MMSoundManagerSoundControlEventTypes.Stop, 33);
An event used to fade a specific sound’s volume over time
/// will fade the sound with an ID of 33 towards a volume of 0.3, over 2 seconds, on an elastic curve MMSoundManagerSoundFadeEvent.Trigger(33, 2f, 0.3f, new MMTweenType(MMTween.MMTweenCurve.EaseInElastic));
This event will let you pause/play/stop/free all sounds playing through the MMSoundManager at once
/// will stop all sounds playing at once MMSoundManagerAllSoundsControlEvent.Trigger(MMSoundManagerAllSoundsControlEventTypes.Stop);
Lets you mute, unmute, play, pause, stop, free or set the volume of a selected track.
/// will pause the entire UI track MMSoundManagerTrackEvent.Trigger(MMSoundManagerTrackEventTypes.PauseTrack,MMSoundManager.MMSoundManagerTracks.UI);
This event will let you order the MMSoundManager to fade an entire track’s sounds’ volume towards the specified FinalVolume
/// will fade the volume of the music track towards 0.5, over 2 seconds, using an ease in cubic tween MMSoundManagerTrackFadeEvent.Trigger(MMSoundManager.MMSoundManagerTracks.Music, 2f, 0.5f, new MMTweenType(MMTween.MMTweenCurve.EaseInCubic));
This event will let you trigger a save/load/reset on the MMSoundManager settings
/// will save settings. MMSoundManagerEvent.Trigger(MMSoundManagerEventTypes.SaveSettings);
The MMSoundManager automatically manages a pool of audio sources to play sounds on. This will help improve performance, as no new audio source will get created/destroyed at runtime. You can define the pool size on the MMSoundManager itself. It should be higher than the maximum amount of sounds you plan on having playing at once.
Sound Manager Settings and AudioMixer
Under the hood, the MMSoundManager uses regular AudioMixer APIs and groups to play sounds on separate tracks. This lets you target these same groups via other systems if you want to. It also lets you use snapshots, and any of the other features of the AudioMixer system. And while the system ships with a default settings scriptable object you can use, you can also create your own, and bind it to your MMSoundManager if you want to. You could also have more than one, and swap between them.