2
\$\begingroup\$

In the Hierarchy i have one Main Camera with Audio Listener. In the Hierarchy I have AudioPanel and two child Sliders.

Audio Panel

And the AudioManager script that attached to the AudioPanel:

using UnityEngine;
using UnityEngine.UI;
using System.Collections;
using System.Collections.Generic;
using System.Linq;


[System.Serializable]


public class AudioManager : MonoBehaviour
{

    public Slider musicVolume;
    public Slider effectsVolume;

    private void SetMusicListenerVolume()
    {
        AudioListener.volume = musicVolume.value;
    }

    public void ApplyMusicSettings()
    {
        SetMusicListenerVolume();
    }

    private void SetEffectsListenerVolume()
    {
        AudioListener.volume = effectsVolume.value;
    }

    public void ApplyEffectsSettings()
    {
        SetEffectsListenerVolume();
    }
}

Now in the Hierarchy I have some Audio Sources components for the sound effects and I want to control them with the Slider (1).

And to control the music sound with the Slider. The music sound have his own Audio Source.

The problem is that the AudioListener in the script control all the Audio Sources. Music and Effects. Or maybe only the Music ? U'm not sure. But when i change both sliders when the game is running it's changing the music volume.

My question/s is how to control with Slider only the volume of the music and with Slider (1) the effects volume ?

And how can i get all the effects audio sources in the script and control the volume of them using the Slider (1) ?

The audio source component of the music is attached to GameObject name Sound. All the other audio sources components are effects and are in some places in the Hierarchy.

\$\endgroup\$
6
\$\begingroup\$

You will need to use an audio mixer.

An audio mixer lets audio sources specify which group they should output to, so you should create two groups, one for sounds effects, and one for music. You need to then expose the attenuation (volume) parameter of each group to code. Then, the music audio source can specify that it should play through the music group, and all the others play through the sound effects group.

Then, in code, you need to get a reference to the audio mixer (for example by adding a reference in a Monobehaviour and assigning it in the inspector) and set the volume of individual groups using the names of the parameters when they were exposed from the inspector.

Note that the range of attenuation is -80 (muted) to 0 (full volume). And it’s not linear, so the slider won’t control the volume smoothly if you just map the volume directly from the slider to attenuation value. You will need to do a conversion using mixer.SetFloat(parameterName, Mathf.Log10(sliderValue) * 20); to get it nice and smooth (assuming sliderValue ranges from 0 to 1). See here for more details.

Note: audio sources created in the editor should be assigned to groups in the inspector. To assign an audio source created at runtime to the correct group via code, use AudioSource.outputAudioMixerGroup

\$\endgroup\$
  • \$\begingroup\$ I done it all but I'm still don't understand how to assign the audio sources to the groups of the mixer via script ? This 3 lines in the Start: The first give me all the Groups from the Audio Mixer: The type of groups is: AudioMixerGroup[] the second and third lines give me the Music audio source. var groups = AllMixerGroups; var gr = GameObject.Find("Music"); music = gr.GetComponent<AudioSource>(); I know that in groups[2] It's the Music group. Now how can i assign the music to the groups[2] ? \$\endgroup\$ – jdoedoe doedoe Dec 31 '17 at 18:45
  • 1
    \$\begingroup\$ music.outputAudioMixerGroup = groups[2]; \$\endgroup\$ – Ed Marty Dec 31 '17 at 19:15
  • \$\begingroup\$ "Note: audio sources created in the editor should be assigned to groups in the inspector." But if for example i have 30 audio sources in many different GameObjects in the hierarchy ? Or you mean that if i want to assign the audio sources to groups in script i should also create the groups in the script ? (Just asking for the knowledge). \$\endgroup\$ – jdoedoe doedoe Dec 31 '17 at 19:33
  • 1
    \$\begingroup\$ If the GameObjects exist in the scene before you hit play, which sounds like it’s the case here, assign them in the inspector. This can be made easier by searching for all GameObjects including an audio source by typing in the hierarchy search area: t:AudioSource, then selecting everything displaying in the hierarchy view and assigning the groups all at once. \$\endgroup\$ – Ed Marty Dec 31 '17 at 19:52
  • 1
    \$\begingroup\$ audioMixer.SetFloat("MyExposedParam", Mathf.Log10(musicVolume.value) * 20); audioMixer.SetFloat("MyExposedParam 1", Mathf.Log10(effectsVolume.value) * 20); \$\endgroup\$ – Ed Marty Jan 1 '18 at 2:49
0
\$\begingroup\$

If all you want is to control the music and sfx volumes through separate sliders, then your AudioManager just needs a few simple changes. :)

public class AudioManager : MonoBehaviour
{

    public Slider musicVolume;
    public Slider effectsVolume;

    // Make sure to plug these in in the inspector.
    public AudioSource musicPlayer;
    public AudioSource effectsPlayer;

    private void Start()
    {
        /*
        All sliders have an onValueChanged event that executes every time the sliders' values are 
        changed (meaning whenever their knobs are moved).

        By hooking them up to the appropriate volume-changing functions (which I added float 
        parameters to, out of necessity), the volumes of the audiosources change with them. 
        */

        musicVolume.onValueChanged.AddListener(SetMusicListenerVolume);
        effectsVolume.onValueChanged.AddListener(SetEffectsListenerVolume);

    }

    private void SetMusicListenerVolume(float volume)
    {
        musicPlayer.volume = volume;
    }

    private void SetEffectsListenerVolume(float volume)
    {
        effectsPlayer.volume = volume;
    }

    public void ApplyMusicSettings()
    {
        // The volume updates itself through the slider's events, so no need to update 
        // the volume in this function.
        //SetMusicListenerVolume();
    }

    public void ApplyEffectsSettings()
    {
        // Or this one.
        //SetEffectsListenerVolume();
    }
}

The comments explain everything.

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.