AudioMixer.SetFloat doesn't work on Awake

I’m trying to load some settings I saved the last time I played and set them right on Awake but it seems like AudioMixer’s SetFloat doesn’t work there…

I think those are the same issue:
http://forum.unity3d.com/threads/audiomixer-setfloat-initialization-problem-beta17.286024/

3 Likes

Yep, filing a bug report and voting on the issue is all you can do really.

Also, wrap your audio initialization in a aptly named method and call that from Start if you haven’t already done that.

Wth, this post is mine and I’m having the same problem as 2 years ago. smh.

15 Likes

Mmm would be good if this was at least noted in the docs or something. Ran into this issue and spent an hour trying to debug it, only to find that it was a unity bug.

1 Like

Same - just filed (yet another) bug report to that effect. I can’t see why SetFloat would work from Start(), but NOT from Awake(). If it is intended behaviour then it would be nice to receive a warning, or a mention of it in the documentation.

On a related note, it would also be nice if it was mentioned somewhere that the second parameter of SetFloat is meant to be in decibels, and not as logic would dictate (0 for “off” and “1” for full loud).

Sometimes, I wish the Unity documentation had a face, then I’d have something to punch over oddities like this.

1 Like

Just encountered this when trying to load settings on Awake. However, it seems to work fine in builds.

@GfK - Here’s a bit of conversion code to use 0-1 volume translated to decibels.

public void SetMasterVol(float vol) //vol: 0 - 1
{
    vol = (1 - Mathf.Sqrt(vol)) * -80f;
    mixer.SetFloat("masterVol", vol);
}
3 Likes

Just to report that it doesn’t work when set in OnEnable() either (which executes after Awake and before Start).

My guess is that the internal works of the AudioMixer is resetting all attenuation to 0dB in it’s own OnEnable() method. I will add a request for the AudioMixer documentation to clarify.

1 Like

And if anyone needs to go the other way around:

public float AttenuationToVol(float attenuation) //attenuation: -80 to 20
{
    return Mathf.Pow(-((vol / -80f) - 1f), 2f));
}
2 Likes

Still not fixed in 2018.4 LTS.
Workaround: Call method in Start() instead of Awake().

3 Likes

It’s wierd, i wrote a sound management script a year ago and the initialization of the float parameters for the audio mixer were called on the Awake() method, all worked well, i even tested the old project i wrote the script for, still worked… now i am working on a new project and used that same script and got this problem, only works with the Start() method.

Edit: Working on Unity 2018.3.0f2

Hmm, August 2019 and this is still causing issues. I found this thread trying to figure out why my Ambient sounds were always at some blasting volume even when I set them in Awake().

Unity 2019.2.6f1
Bug still exists in November 2019, but only in the Editor.
I’ve reported a bug for the editor. FogBugz link.

2 Likes

From looking at the bug that @deeprest opened, apparently setting AudioMixer parameters in Awake is undefined behavior. The parameters must be set in Start. Weird…but there you have it.

Won’t it be possible to create a method to set the defalut values of the AudioMixer that could run from Awake?
My entire framework initialises every system that can be configurable via loading a save file in Awake, all the input options, graphics options, language, accessibility - everything, but with audio I have to run a coroutine that runs after 0.01 seconds after the Awake in order to load the values from the save file. It’s kinda hacky.
Also, if it does work in builds, is it a defined behaviour? Like, can I make different methods to run if the game runs in editor and in the build, and it it’s the build - will the changing of the values work in Awake flawlessly?

If you load the settings file synchronously in Awake(), can you not apply the values in Start()? Start is called just before the first Update().

I assume not. You must determine if it’s worth your time to rely on “undefined behaviour”. If it seems to work, then great, but it might not work for everyone/all platforms the same, so you might need to put time into fixing it later anyway.

For the few audio settings I have, I handle them explicitly in Start(). Before this thread, I did something like the code below. We now know the #if directive should not be necessary, and is probably a bad idea.

  void Start()
  {
#if UNITY_EDITOR
    // workaround for Unity Editor bug where AudioMixer.SetFloat() does not work in Awake()
    mixer.SetFloat( "MasterVolume", Util.DbFromNormalizedVolume( FloatSetting["MasterVolume"].Value ) );
    mixer.SetFloat( "MusicVolume", Util.DbFromNormalizedVolume( FloatSetting["MusicVolume"].Value ) );
    mixer.SetFloat( "SFXVolume", Util.DbFromNormalizedVolume( FloatSetting["SFXVolume"].Value ) );
#endif
  }

I handle all settings generically in Awake(), then apply audio settings like this in Start().

1 Like

Ugh. I have different behaviour on two different scripts in the same project. In one script calling SetFloat(…) from Awake() is working fine, in another it’s doing nothing.

Thanks for the link.

It should be noted that the statements in the bug response and the docs page for AudioMixer.SetFloat(…) directly contradict each other. I gave feedback to that effect on the docs page, about to bug report it, too.

Hey,
If you have to use AudioMixer.SetFloat() on Awake(), try using async method instead.

using System.Threading.Tasks;
void Awake()
{
    DelayedUpdateVolume();
}
 
 
async void DelayedUpdateVolume()
{
    await Task.Delay(100);
    myAudioMixer.SetFloat("BGM", myVolume);
}

This async method still works even if the GameObject this script is attached to is disabled during Awake(), unlike Coroutine.

1 Like

This thread is NOT about initialization when object might be / will be / is disabled - that’s a different - and thus unrelated - problem

Moreover, shoving a Sleep is an band aid of the worst kind - it NEVER solves it properly