I really appreciate how you write comments outlining what you’re going to do before writing the actual code. It clearly explains your thought process, and as a viewer, it couldn’t be more helpful. Thank you so much for this tutorial!
I really appreciate you taking the time to not just show the solution to the problem and add a code snippet to copy. You show how it can be done, explain the code and even address problems / negative examples. This is perfect for learning. Thank you very much!
I'm just getting started learning Unity and am about to add audio to my first solo project. I definitely would have fallen for the beginner's traps shown here. It really seems worthwhile to go the extra mile to avoid a buggy mess. Thanks for the solid info and great job on the tutorial!
This video made my job much easier. I decided to leave the sound part until last, along with a lot of prefabs. The only thing I will do now is to give all the sounds as variables to the soundFxManager and call those sounds from the prefabs. Otherwise I would have to add sounds to all of them one by one. thanks a lot.
Really cool tutorial, something i would change to avoid code repetition is to pick the random clip in the PlayRandomSound function but then call the original PlaySound function and pass the random audioclip
I've never seen anyone instantiate and destroy AudioSource objects like that. Each of my sound managers has a single audio source mapped to an audio mixer group and I use PlayOneShot() to play sound effects. Of course that doesn't use spatial audio though so if you really want the surround sound effect I guess you need an approach similar to yours. I would probably implement object pooling though so as not create a bunch of garbage and get lag spikes.
yea I was never able to find a solution that I was 100% happy with, so I made this one. PlayClipAtPoint has the spatial audio, but it uses Instantiate/Destroy with no way to change that as far as I can tell. PlayOneShot is great except for the spatial audio being a bit lacking. This way, you get the spatial audio, as well as the abillity to easily swap it into an object pooling system (and by extension, control your voice count fairly easily so you don't go above the threshold.)
@@sasquatchbgames Hey I wanted to share with you an implementation where you actually can add a mixergroup to an audiosource that is instantiated at runtime. I had this same problem so I managed to get this solution up and working. You need to put your mixer in the "Resources" folder. Then you can get a reference to it in script with _myMixer = Resources.Load("stringPath") as Audiomixer; (Example "Resources/Mixers/Mainmixer") THEN You can get a reference to the mixergroup by AudioMixerGroup _sfxGroup = _myMixer.FindMatchingGroups("stringName") THEN You can assign it to an audiosource at runtime by. _exampleAudioSource.outputAudioMixerGroup = _sfxGroup; AND now you can instantiate Audiosources at runtime while still having control of their mix!
Object pooling was my first thought as well. Im debating implementing object pooling for this system, but I'm not sure if it's worth it in the project I'm working on because there would only ever be like 3 sound effects playing at once, but you never know if that'll change
This is absolutetly fucking amazing. Thank you yo! You've saved our deadlined project by telling us how NOT to do it aswell, thats what I was thinking to do first xD
The log10(level) * 20 is the aproximative real world formula to calculate the power of sound. So what is the value of X for x.pow(10) == level. Also that was a great tutorial, I will be using yous system in my current project.
Great video. Just wondering if we should follow the same setup within the music manager such as using a prefab game object (i.e. "MusicObject) and make a singleton as well?
Nicely done. All the most important points covered. Something I would add is that in addition to playing random clips, it’s nice also randomly setting the pitch and volume, which can give a sense that you have more asset variation. The issue then is that destroying by clip length will not adapt to the length change from pitch adjustment. To account for this, you can set the destroy time for the spawned AudioSource to: audioSource.clip.length/audioSource.pitch. Hope that helps!
I want to add: it’s cool seeing your journey. Glad you’re sharing it through CZcams :) I do technical game audio professionally (full time - I’m not looking for money here), so I just thought I’d extend that if you run into audio issues with your game you can hit me up for some advice. Cheers and best of luck!
If there is a single sfx audio manager what would happen in the case of multiple sfx playing at the same time? Or is this a case were we wouldnt want to make a singleton
How can I make it so these settings persist using PlayerPrefs? I have added a save button and the values are stored correctly, in my GameManager's on Awake function I load these values, set them in the SoundMixerManager and also in my OptionsMenuUI to the sliders. The sliders continue to be full.
Instead of instantiating and destroying the audio source, As we would still assign the audio clip we want, could object pooling be used and maybe as a precaution remove the clip from the audio source before returning source to pool?
This is a great solution for an audio manager however how might this implement a Stop() function? If say you had an audio sound that you wanted to stop mid sfx then how would you reference the audioSource? Say i have a light sound that plays when a light is active. When I turn off that light how do I make the sound stop with it?
Před 5 měsíci
Nice tuto, BUT, how to play a sound FX from a Button?
Every button has a onClick event in the inspector, add the SoundManager into it, and active the playSoundFX method. All of this can be done in the inspector, on the button component. Or you can add a reference for the button into a script and add a onClickListenter on it, then call the PlaySoundFX method this way.
Hello!!! Thank you for very cool tutor! But how can I save these values in PlayerPrefs and then load them afterwards, to save the settings? public AudioMixerGroup Mixer; private void Start() { GetComponentInChildren().value = PlayerPrefs.GetFloat("MusVolume", 1); GetComponentInChildren().value = PlayerPrefs.GetFloat("FxVolume", 1); } public void MusicVolume(float volume) { Mixer.audioMixer.SetFloat("MusicVolume", Mathf.Log10(volume) * 20f); PlayerPrefs.SetFloat("MusVolume", volume); } public void SFXVolume(float volume) { Mixer.audioMixer.SetFloat("SfxVolume", Mathf.Log10(volume) * 20f); PlayerPrefs.SetFloat("FxVolume", volume); }
Won't this cause performance issues? like you can't use object pooling her, looks like it will generate a lot of garbage collection since we keep destroy and respawn audio objects especially when you have multiple sounds for the same character.
Probably a good optimisation to add on top if you end up producing too much garbage. Remember, only optimize when it becomes an issue, focus on getting the game out
I really appreciate how you write comments outlining what you’re going to do before writing the actual code. It clearly explains your thought process, and as a viewer, it couldn’t be more helpful. Thank you so much for this tutorial!
rare W
Probably the best Unity audio tutorial I have seen so far.
Agreed - so incredibly helpful!
I really appreciate you taking the time to not just show the solution to the problem and add a code snippet to copy.
You show how it can be done, explain the code and even address problems / negative examples.
This is perfect for learning. Thank you very much!
I'm just getting started learning Unity and am about to add audio to my first solo project. I definitely would have fallen for the beginner's traps shown here. It really seems worthwhile to go the extra mile to avoid a buggy mess. Thanks for the solid info and great job on the tutorial!
This was immensely helpful. Also, the way you made dividers in the hierarchy was one of those "why didn't I think of that??" things. Thanks a bunch!
I love these kind of managers! I have a 2D project template and each time I find a gem like this I work it in there. Thanks a lot!
OMG THANK YOU SOOOO MUCH I WAS SITTING ON THIS FOR 2 DAYS AND NOW I HAVE PUT SOUNDS AND SFX ON EVERYTHING THANKS TO THX SO MUCH!!!!!
you increased my confidence ngl
I am very stunned ! The title "...the RIGHT WAY" is really not an exaggeration. Thank you for that ! FYI for other dev's: Works under 2023.3
This is the most efficient sound manager I've ever tried, you have my respect man!
You should combine this with codemonkeys soundmanager, it's the ultimate sound system
Thanks! This will be my video reference to create audio systems.
You should make a guide on how to create that kind of pause menu!
This video made my job much easier. I decided to leave the sound part until last, along with a lot of prefabs. The only thing I will do now is to give all the sounds as variables to the soundFxManager and call those sounds from the prefabs. Otherwise I would have to add sounds to all of them one by one.
thanks a lot.
Really cool tutorial, something i would change to avoid code repetition is to pick the random clip in the PlayRandomSound function but then call the original PlaySound function and pass the random audioclip
You really make the best tutorials!
I've never seen anyone instantiate and destroy AudioSource objects like that. Each of my sound managers has a single audio source mapped to an audio mixer group and I use PlayOneShot() to play sound effects. Of course that doesn't use spatial audio though so if you really want the surround sound effect I guess you need an approach similar to yours. I would probably implement object pooling though so as not create a bunch of garbage and get lag spikes.
yea I was never able to find a solution that I was 100% happy with, so I made this one.
PlayClipAtPoint has the spatial audio, but it uses Instantiate/Destroy with no way to change that as far as I can tell. PlayOneShot is great except for the spatial audio being a bit lacking.
This way, you get the spatial audio, as well as the abillity to easily swap it into an object pooling system (and by extension, control your voice count fairly easily so you don't go above the threshold.)
@@sasquatchbgames Hey I wanted to share with you an implementation where you actually can add a mixergroup to an audiosource that is instantiated at runtime. I had this same problem so I managed to get this solution up and working.
You need to put your mixer in the "Resources" folder. Then you can get a reference to it in script with
_myMixer = Resources.Load("stringPath") as Audiomixer; (Example "Resources/Mixers/Mainmixer")
THEN
You can get a reference to the mixergroup by
AudioMixerGroup _sfxGroup = _myMixer.FindMatchingGroups("stringName")
THEN
You can assign it to an audiosource at runtime by.
_exampleAudioSource.outputAudioMixerGroup = _sfxGroup;
AND now you can instantiate Audiosources at runtime while still having control of their mix!
@@iiropeltonen awesome man, thanks!
Object pooling was my first thought as well. Im debating implementing object pooling for this system, but I'm not sure if it's worth it in the project I'm working on because there would only ever be like 3 sound effects playing at once, but you never know if that'll change
WHATTT!? your stupid 😅
You saved so much time of mine. Thanks a lot.
This is absolutetly fucking amazing. Thank you yo! You've saved our deadlined project by telling us how NOT to do it aswell, thats what I was thinking to do first xD
Hey, you didn't show how to call the menu, nor how to make the sliders :(
The log10(level) * 20 is the aproximative real world formula to calculate the power of sound. So what is the value of X for x.pow(10) == level. Also that was a great tutorial, I will be using yous system in my current project.
Thank you. Very helpful video!!
Amazing tutorial :)
Great Tutorial, as always.
Thanks again! 🙂
Great video. Just wondering if we should follow the same setup within the music manager such as using a prefab game object (i.e. "MusicObject) and make a singleton as well?
Nicely done. All the most important points covered.
Something I would add is that in addition to playing random clips, it’s nice also randomly setting the pitch and volume, which can give a sense that you have more asset variation.
The issue then is that destroying by clip length will not adapt to the length change from pitch adjustment. To account for this, you can set the destroy time for the spawned AudioSource to:
audioSource.clip.length/audioSource.pitch.
Hope that helps!
I want to add: it’s cool seeing your journey. Glad you’re sharing it through CZcams :)
I do technical game audio professionally (full time - I’m not looking for money here), so I just thought I’d extend that if you run into audio issues with your game you can hit me up for some advice. Cheers and best of luck!
fantastic explanations
great video thank you thank you
If there is a single sfx audio manager what would happen in the case of multiple sfx playing at the same time? Or is this a case were we wouldnt want to make a singleton
How can I make it so these settings persist using PlayerPrefs? I have added a save button and the values are stored correctly, in my GameManager's on Awake function I load these values, set them in the SoundMixerManager and also in my OptionsMenuUI to the sliders.
The sliders continue to be full.
Fixed it by loading the values from PlayerPrefs in Start() instead of Awake(). :D
Do you know how to set it up to play an audio clip before playing a looping, continuous piece of music?
my dear good sir, Mathf.Log10(value) * 20f ..... where value ranges from 0 to -80
log(-ve numbers) is giving NaN output ..how's it working for you
Thanks!
Thank you!
nice tutorials
Instead of instantiating and destroying the audio source, As we would still assign the audio clip we want, could object pooling be used and maybe as a precaution remove the clip from the audio source before returning source to pool?
Can I do this same thing but instead of creating my own sound clips array, use the built in Random Audio Container in unity? v helpful tutorial
what does it mean if I get and error in Unity that says "The name 'volume' does not exist in the current context?"
This is a great solution for an audio manager however how might this implement a Stop() function? If say you had an audio sound that you wanted to stop mid sfx then how would you reference the audioSource?
Say i have a light sound that plays when a light is active. When I turn off that light how do I make the sound stop with it?
Nice tuto, BUT, how to play a sound FX from a Button?
Every button has a onClick event in the inspector, add the SoundManager into it, and active the playSoundFX method.
All of this can be done in the inspector, on the button component.
Or you can add a reference for the button into a script and add a onClickListenter on it, then call the PlaySoundFX method this way.
Hello!!! Thank you for very cool tutor! But how can I save these values in PlayerPrefs and then load them afterwards, to save the settings?
public AudioMixerGroup Mixer;
private void Start()
{
GetComponentInChildren().value = PlayerPrefs.GetFloat("MusVolume", 1);
GetComponentInChildren().value = PlayerPrefs.GetFloat("FxVolume", 1);
}
public void MusicVolume(float volume)
{
Mixer.audioMixer.SetFloat("MusicVolume", Mathf.Log10(volume) * 20f);
PlayerPrefs.SetFloat("MusVolume", volume);
}
public void SFXVolume(float volume)
{
Mixer.audioMixer.SetFloat("SfxVolume", Mathf.Log10(volume) * 20f);
PlayerPrefs.SetFloat("FxVolume", volume);
}
wait so if I have 20 coins at a place in my game and i collect them ..i will have to spawn 20 audiosources ?
yes
Won't this cause performance issues? like you can't use object pooling her, looks like it will generate a lot of garbage collection since we keep destroy and respawn audio objects especially when you have multiple sounds for the same character.
Probably a good optimisation to add on top if you end up producing too much garbage. Remember, only optimize when it becomes an issue, focus on getting the game out
For me it doesn't create a soundFXObject in the inspector
under the script for the manager that is
Can this be used in 3D games too? Haven't tested it yet but I just wanna be sure
Of course, no difference.
I use it in my 3D game.
What about saving the value of voiumes ?? These will be lost each time the scene reloads? or
not?
did you find a solution? wondering the same thing
@@ThePoePoee playerprefs can be used I think
@@mustafa_unitydevyes use player prefs and save it as float or int
Do the sliders stop working after reloading scene?
yes
First
wull
what's the point of this comment exactly