Search Unity

  1. Good news ✨ We have more Unite Now videos available for you to watch on-demand! Come check them out and ask our experts any questions!
    Dismiss Notice
  2. Ever participated in one our Game Jams? Want pointers on your project? Our Evangelists will be available on Friday to give feedback. Come share your games with us!
    Dismiss Notice

AudioMixer Music Level - UI Slider Problem ( Solved )

Discussion in 'Scripting' started by PlaymintDev, Mar 30, 2016.

  1. PlaymintDev

    PlaymintDev

    Joined:
    Jan 11, 2014
    Posts:
    348
    Hi,

    I have the following code to control the volume of the music in my scene :

    Code (CSharp):
    1. using UnityEngine;
    2. using System.Collections;
    3. using UnityEngine.Audio;
    4.  
    5. public class musicVolumeControl : MonoBehaviour {
    6.  
    7.     // Drag our given AudioMixer here
    8.     [Header("AudioMixer - Drag Here")]
    9.     public AudioMixer masterMixer;
    10.  
    11.     public void SetMusicLevel(float musicLevel)
    12.     {
    13.         masterMixer.SetFloat("musicVolume", musicLevel);
    14.     }
    15. }
    16.  
    PROBLEM : When the pause menu is initiated, the player can control the volume of the music in the game via a slider, at the moment, this works perfectly, let's assume the volume is set at 75%. So, the player comes out of the pause menu, plays the game for a bit, then invokes it again, the slider remembers where the player last positioned the volume slider at 75%, excellent !

    But
    , if the player decides to restart the level from the pause menu, the level 'restarts', and the music level is still at 75%, as one would expect, but if the pause menu is invoked again, the volume slider is at 100%, even though the music is only at 75% volume, any ideas how I might fix this ?
     
  2. PlaymintDev

    PlaymintDev

    Joined:
    Jan 11, 2014
    Posts:
    348
    Sneaky bump, anyone... ?

    Short of forcing the volume to reset to 100% on the load of each scene ( which the end user would probably get annoyed with ), not sure how to fix this ?
     
  3. PlaymintDev

    PlaymintDev

    Joined:
    Jan 11, 2014
    Posts:
    348
    Would there be a way to check volume level on level load and then set sliders accordingly ?
     
  4. Trexug

    Trexug

    Joined:
    Dec 2, 2013
    Posts:
    88
    Make an additional method:
    Code (csharp):
    1.  
    2. public float GetMusicLevel()
    3. {
    4.     return masterMixer.GetFloat("musicVolume");
    5. }
    6.  
    And, when opening the pause menu, set the slider's value to the returned value.
     
  5. PlaymintDev

    PlaymintDev

    Joined:
    Jan 11, 2014
    Posts:
    348
    @Trexug

    Thanks for your reply, much appreciated, :) I'll look into this and try it out, if I have any problems I'll report back here.

    Regards.
     
  6. PlaymintDev

    PlaymintDev

    Joined:
    Jan 11, 2014
    Posts:
    348
    More difficult than I thought. And clearly I'm out of my depth also... :(

    So, on my slider, I have the following code, this is driven by the slider when the pause menu is invoked :

    Code (CSharp):
    1. using UnityEngine;
    2. using System.Collections;
    3. using UnityEngine.Audio;
    4.  
    5. public class musicVolumeControl : MonoBehaviour {
    6.  
    7.     // Drag our given AudioMixer here
    8.     [Header("AudioMixer - Drag Here")]
    9.     public AudioMixer masterMixer;
    10.  
    11.     public void SetMusicLevel(float musicLevel)
    12.     {
    13.         masterMixer.SetFloat("musicVolume", musicLevel);
    14.     }
    15.  
    16. }
    And, on the same slider button, I have the following code, NOW, in my mind, each time my pause button is invoked, the following code gets the currentMusicLevel and then sets it to the slider ( ? ), except it does NO such thing, each time my scene is restarted, the slider is still at 100%, even when it has been set at much lower values. Would appreciate any 'more' help ! :oops:

    Code (CSharp):
    1. using UnityEngine;
    2. using System.Collections;
    3. using UnityEngine.Audio;
    4.  
    5. public class setMusicVolumeSlider : MonoBehaviour {
    6.  
    7.     // Drag our given AudioMixer here
    8.     [Header("AudioMixer - Drag Here")]
    9.     public AudioMixer masterMixer;
    10.  
    11.     void OnEnable ()
    12.     {
    13.         float currentMusicLevel;
    14.         masterMixer.GetFloat ("musicVolume", out currentMusicLevel);
    15. //        return currentMusicLevel;
    16.         masterMixer.SetFloat("musicVolume", currentMusicLevel);
    17.     }
    18. }

    EDIT : I've noticed if I use

    Code (CSharp):
    1. Debug.Log("Current Music Volume : "+currentMusicLevel);
    it returns a value of 0, why ?
     
    Last edited: Mar 31, 2016
  7. Trexug

    Trexug

    Joined:
    Dec 2, 2013
    Posts:
    88
    I don't know how your slider code looks, but in the code you have posted above you are not changing any value which would be accessible to the slider - you are reading the value from the mixer and then writing the same value back to the mixer.

    Let me give you an example of how your slider code could look:

    Code (csharp):
    1.  
    2. using UnityEngine;
    3. using UnityEngine.Audio;
    4.  
    5. public class SliderExample : MonoBehaviour
    6. {
    7.     public AudioMixer mixer;
    8.  
    9.     private void OnGUI()
    10.     {
    11.         const string VOLUME_NAME = "musicVolume";
    12.  
    13.         float volume;
    14.         mixer.GetFloat(VOLUME_NAME, out volume);
    15.         float newValue = GUI.HorizontalSlider(new Rect(25, 25, 100, 30), volume, -80F, 20.0F);
    16.         mixer.SetFloat(VOLUME_NAME, newValue);
    17.     }
    18. }
    19.  
    20.  
    In this example we read the value from the mixer to a variable called volume, which is used when displaying the slider. The new value from the slider (when the player changes the value) is then set on the mixer. The slider ranges from -80 to +20 which makes sense if musicVolume controls the volume.

    In your case you have a musicVolumeControl component which you are using for modifying the mixer, which is fine. You need the slider to retrieve the current value either from the mixer itself or from a component which has access to the value (like musicVolumeControl given that you add a GetMusicLevel method). When the player changes the value in the slider, you should set the new value either on the mixer itself or on a component which has access to the mixer (like musicVolumeControl).
     
    PlaymintDev likes this.
  8. PlaymintDev

    PlaymintDev

    Joined:
    Jan 11, 2014
    Posts:
    348
    SOLVED !!

    Finally managed to figure it out ! :D

    So, on my slider is the following code ( back to the original code ) :

    Code (CSharp):
    1. using UnityEngine;
    2. using System.Collections;
    3. using UnityEngine.Audio;
    4.  
    5. public class musicVolumeControl : MonoBehaviour {
    6.  
    7.     [Header("AudioMixer - Drag Here")]
    8.     public AudioMixer masterMixer;
    9.  
    10.     public void SetMusicLevel(float musicLevel)
    11.     {
    12.         masterMixer.SetFloat("musicVolume", musicLevel);
    13.     }
    14. }
    and a new script attached to my 'pause' canvas menu, invoked when the pause menu is enabled : -

    Code (CSharp):
    1. using UnityEngine;
    2. using System.Collections;
    3. using UnityEngine.UI;
    4. using UnityEngine.Audio;
    5.  
    6. public class musicVolumeInit : MonoBehaviour {
    7.  
    8.     [Header("AudioMixer - Drag Here")]
    9.     public AudioMixer masterMixer;
    10.  
    11.     [Header("Music Volume Slider - Drag Here")]
    12.     public Slider volumeSlider;
    13.  
    14.     float currentMusicLevel;
    15.  
    16.     void Start()
    17.     {
    18.         masterMixer.GetFloat("musicVolume", out currentMusicLevel);
    19.         Debug.Log("Current Music Volume : "+currentMusicLevel);
    20.  
    21.         volumeSlider.GetComponent<Slider>().value = currentMusicLevel;
    22.     }
    23. }
    So, I declared a new public Slider object, I then drag my ui slider into the given slot and my audiomixer into the given slot, I get the currentMusicLevel and pass that value to the slider value component. It was a pain, but finally got there !
     
    Last edited: Apr 1, 2016
  9. RealSoftGames

    RealSoftGames

    Joined:
    Jun 8, 2014
    Posts:
    220
    ok i have a couple of things after reading some of the post here, why not use player prefs for something as simple as this. or a scriptable object. this way it stays persistent between games and levels, hope this comes in handy.

    Code (CSharp):
    1. using System.Collections;
    2. using System.Collections.Generic;
    3. using UnityEngine;
    4. using UnityEngine.Audio;
    5. using UnityEngine.UI;
    6.  
    7. public class AudioController : MonoBehaviour
    8. {
    9.     public AudioMixer mixer;
    10.     public Slider musicSlider, sfxSlider;
    11.  
    12.     private void Start()
    13.     {
    14.         LoadPref();
    15.     }
    16.  
    17.     public void SetMusixLevel(float value)
    18.     {
    19.         mixer.SetFloat("MusicVol", value);
    20.         PlayerPrefs.SetFloat("MusicVol", value);
    21.         PlayerPrefs.Save();
    22.     }
    23.  
    24.     public void SetSFXLevel(float value)
    25.     {
    26.         mixer.SetFloat("SFXVol", value);
    27.         PlayerPrefs.SetFloat("SFXVol", value);
    28.         PlayerPrefs.Save();
    29.     }
    30.  
    31.     private void LoadPref()
    32.     {
    33.         mixer.SetFloat("MusicVol", PlayerPrefs.GetFloat("MusicVol"));
    34.         musicSlider.value = PlayerPrefs.GetFloat("MusicVol");
    35.  
    36.         mixer.SetFloat("SFXVol", PlayerPrefs.GetFloat("SFXVol"));
    37.         sfxSlider.value = PlayerPrefs.GetFloat("SFXVol");
    38.     }
    39. }
     
    Gerard_Slee likes this.
unityunity