How would you design a Sound Manager, then?

In this course your advice was to never call a script “Manager”, since there is probably a better name, and most importantly to use the singleton pattern as few times as possible.

But then, what would be the best practice to design a Sound Manager? By “Sound Manager” I mean a very handy game object which has the function to play background music and sound effects. Its use is widespread and a lot of other scripts need to access it to be able to play sounds.

My go to solution has been, as you might have imagined, to use a singleton and then call it anywhere simply using SoundManager.instance.PlaySound(...).

What is the best practice in creating such an object? Or is the singleton pattern good enough? Is there a better name?

I think the biggest problem with the term “Manager” is that for a very long time, especially in Unity, it was used and abused as a catch all class name for everything… Eventually, it became a meaningless addition to a script name.
For example: I would make your Sound Manager a BackgroundMusicPlayer. It’s very clear what it does, ti plays background music. You don’t need the Sound Manager to play audio clips, as if your goal is to spawn a sound effect at a specific location, you can use AudioSource.PlayClipAtPoint(), and the ideal solution for sound effects is to have them played by AudioSource components attached to the GameObjects they are associated with.

With regards to Singletons, while they’re not ideal, they are not always evil. I’ll let you in on a dirty little secret, the PeristentObjectsPrefab method is actually… another form of Singleton. It’s just offsetting the management of the Singleton enforcement mechanism to a single class instead of putting in each class that needs to be a Singleton.

Thank you for your anwser!

I think BackgroundMusicPlayer really fits!
However I’m not sure about the sound effects, isn’t it better - in the case of 2D games at least - to always play sounds in the same point? (I think this advice comes from one of your courses.) In this case it is very handy to have a central object managing sound effects playing.
As of now I’m only doing 2D games and my solution would be to create a SoundEffectsPlayer singleton whose instance can be accessed everywhere. Or maybe it would be better to create an object with a tag and get it using its tag? Not sure the pros and cons of the two possibilites.

Isn’t PersistentObjectsPrefab more a “collection of objects that persists between scenes” rather than a singleton? (Since there is no way to access it via a central instance variable?)

AudioSource.PlayClipAtPoint() is still the right call here.

AudioSource.PlayClipAtPoint(clip, Camera.main.transform.position, 1);

You could also take advantage of an interesting feature in C#, called an extension method…

public static class AudioExtension
{
     public static void PlayMono(this AudioClip clip)
     {
            AudioSource.PlayClipAtPoint(clip, Camera.main.transform.position, 1);
     }
}

Now, with this extension method in place (it must be in a static class, and be a static method!) you can call your AudioClip like this:

clip.PlayMono();

More about Extension methods: Extension Methods - C# Programming Guide | Microsoft Docs

It’s still technically a Singleton. The crux of a Singleton isn’t the instance variable, it’s what I call the Highlander Principle: There can be only one. It’s any mechanism to ensure that one, and only one instance of an object can be in existence at any one time.

1 Like

This may be too advanced and beyond the scope of the question, but I would use Fmod (which is free and very well integrated with Unity), and/or at least try to understand how Fmod is architectured and replicate something similar.

In other words, I would use an event, then have the Sound “manager”, of which there could now be many, to subscribe to these events.

More precisely I would have two new MonoBehaviours, one called something like AudioEventListener and another called AudioEventEmitter, then place them in relevant GameObjects as needed.

The advantages are multiple, namely:

  • not singleton (you could have an Sound “manager” manages only FX sound, or only music, or only of a certain class like weapons sounds, or sounds based of some context like those are are close and those that are far, etc…

  • decoupled and reusable: the point is that your code wouldn’t know which sound manager handle this, you just raise the event and let the sound architecture you put in place deal with it. If working with a team, you could even let the sound guy work on designing the audio as he sees fit using those events and handlers, while the rest of the team - designers and programmers - wouldn’t need to worry about sound at all… you could even start with placeholders sounds, or even no sounds, at the beginning so not too invest too much time in choosing the audio at the beginning of the project, while leaving the project open and flexible and powerful enough to be amended by the audio guy at a latter date

  • performance: these don’t need to be Unity events and could even be C# events that you tailor to your project. Most importantly, they could perform in a way that is very optimum to your project by, say, even running in a separate thread, just like Fmod does…

1 Like

I only recently learned about the extension method, but you’re right, they could work great in this case! Thanks!

Thank you for clearing that out!

Cool! I thought FMOD was not free. Anyways, I agree that understanding its architecture could help me a lot here.

If I understood correctly, every game object that needs to emit sounds should have both an AudioEventEmitter component (which has the purpose of emitting events when certain sounds should be played) and an AudioEventListener component (which should react to the previous events and play sounds as a result). I’m not entirely sure why it wouldn’t suffice to emit general events from other scripts (such as onBulletHit or onDeath) and then have simply a listener that plays audio in response. But maybe I’m not yet too confident about C# events.

To understand FMOD architecture, what do you suggest? (Perhaps a simple tutorial on how to use FMOD would do.)

Fmod has a really good beginner tutorial in https://www.fmod.com/learn

Essentially the tutorial makes you change the sound for the Unity Micro Kart project, using FMod as the replacement.

Fmod is really good because it features its own software outside of Unity where you can do many things, including managing your own library of sounds and music. So if you have say thousands of music clips you don’t have to upload them all and manage them all: Fmod studio will do that for you and only bring over the audio file that you need, all the while letting you test the sound in the Unity editor or at runtime.

But because it takes place outside of Unity - in FMod studio using its own thread - it does take some getting used to.

1 Like

I see, thank you both, you gave a lot of useful information to process!

This topic was automatically closed 24 hours after the last reply. New replies are no longer allowed.

Privacy & Terms