Unity I'm having trouble keeping the saved sound values.

zenergyblack

Newbie
Mar 29, 2022
25
3
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Audio;
using UnityEngine.UI;

public class Volumen : MonoBehaviour
{
[SerializeField] private AudioMixer myMixer;
[SerializeField] private Slider sliderSFX;
[SerializeField] private Slider sliderBGM;
[SerializeField] private Image imagenMuteBGM;
[SerializeField] private Image imagenMuteSFX;
[SerializeField] private Image imagenLowVolumeSFX;
[SerializeField] private Image imagenNormalVolumeSFX;
[SerializeField] private Image imagenLowVolumeBGM;
[SerializeField] private Image imagenNormalVolumeBGM;

private void Awake()
{
if (PlayerPrefs.HasKey("SFX"))
{
LoadSFXVolumen();
}
else
{
SetSFXVolume();
}

if (PlayerPrefs.HasKey("BGM"))
{
LoadBGMVolume();
}
else
{
SetBGMVolume();
}
EstoyMuted();
}

public void SetSFXVolume()
{
float volumeSFX = sliderSFX.value;
myMixer.SetFloat("SFX", Mathf.Log10(volumeSFX) * 20);
PlayerPrefs.SetFloat("SFX", sliderSFX.value);
EstoyMuted();
PlayerPrefs.Save();
}

public void SetBGMVolume()
{
float volumeBGM = sliderBGM.value;
myMixer.SetFloat("BGM", Mathf.Log10(volumeBGM) * 20);
PlayerPrefs.SetFloat("BGM", sliderBGM.value);
PlayerPrefs.Save();
EstoyMuted();
}

private void LoadSFXVolumen()
{
sliderSFX.value = PlayerPrefs.GetFloat("SFX");
SetSFXVolume();
}

private void LoadBGMVolume()
{
sliderBGM.value = PlayerPrefs.GetFloat("BGM");
SetBGMVolume();
}

public void EstoyMuted()
{
myMixer.GetFloat("SFX", out float volumeSFX);
myMixer.GetFloat("BGM", out float volumeBGM);

imagenMuteSFX.enabled = false;
imagenLowVolumeSFX.enabled = false;
imagenNormalVolumeSFX.enabled = false;

if (volumeSFX <= -80f)
{
imagenMuteSFX.enabled = true;
}
else if (volumeSFX <= -6f)
{
imagenLowVolumeSFX.enabled = true;
}
else
{
imagenNormalVolumeSFX.enabled = true;
}

imagenMuteBGM.enabled = false;
imagenLowVolumeBGM.enabled = false;
imagenNormalVolumeBGM.enabled = false;

if (volumeBGM <= -80f)
{
imagenMuteBGM.enabled = true;
}
else if (volumeBGM <= -6f)
{
imagenLowVolumeBGM.enabled = true;
}
else
{
imagenNormalVolumeBGM.enabled = true;
}
}


}

I've been trying for a while, but I can't find the error. I managed to make the graphics options work, etc. But sound is the only one that doesn't save the values for me.

The thing is, when I enter the game (main menu), the soundtrack plays super loud, and if I go to the options (after previously entering them), the sliders are saved and the soundtrack volume decreases. But until I enter the options, the sound doesn't adjust.
 

Tompte

Member
Dec 22, 2017
214
152
Have you tried setting a breakpoint in any of the methods to make sure they actually get called when you start the game?
Awake only gets called if the GameObject is active.
 

LS47

Member
Oct 5, 2021
143
294
You're trying to load the values from PlayerPrefs, but when do you actually register them ? I haven't seen any PlayerPrefs.SetFloat() anywhere in your code, so the values just get assigned to the AudioMixer but are never written back in the prefs.

Also, please use Insert>Code in the toolbar to format your code. It's not hard to do and it would make it easier for us to help you by making your code actually readable.

Edit : Case in point, I misunderstood what your code was doing. Basically, you're only saving the prefs once in the Awake() method, but if you change the values of your sliders, the Set() method is never called again, so the prefs.SetFloat() are never called either.
 

eugeneloza

Member
Jan 2, 2022
205
91
But until I enter the options, the sound doesn't adjust.
Most likely because Options game object is inactive. Awake is called only on active game objects. Either make the GameObjects to which this script is attached active and disable it when the game starts, or attach this script to something that is initially active.
Also you can significantly simplify your code by just using "default value" of the volume:
C:
someSlider.value = PlayerPrefs.GetFloat("SFX", 1.0f);
HOWEVER, note one well-known bug. Sometimes things like AudioMixer behave wildly and the values you send are simply ignored until the first frame of the game. But when the first frame of the game is shown it's already too late, because this 1/30 of second the sound already plays at full throttle.

So what to do:

* Set default volumes on Mixer to -80
* Load and apply volume to Mixer in Start, not Awake. (and make sure the object that does so is enabled)