AudioMixer.SetFloat doesn't work on Awake

True, in that case it is better to just call the SetFloat in Start since it is called right in the next frame.

Yes, I just suggested an alternative workaround to that problem. It persisted long enough for me to wait for Unity to fix it

2019.4.3f1 I just encountered this bug. Thanks to this thread for Start fix.

well no - in that case it’s better to sync your all game systems startup - including audio one - after some fixed delay
so a timeout can (and until there’s nothing better - should) be used, only not be specific to a single SetFloat on a specific mixer on a specific game object possibly in a specific scene and so on
so @NGC6543 's code snippet shouldn’t be taken literally but rather as an idea to solve the issue (which it does - unfortunately - good enough)

I found a work around based on the information here in the 2019.4.5 LTS version. So thanks for that.

But my goodness, I hope Unity fixes this… Maybe there is some reason why it’s like this, but I haven’t found anything.

They responded to my bug report that they couldn’t reproduce it and asking for a repro project. I’ve not had time to oblige.

2 Likes

Damn this bug! Just found it in 2019.4RST! Hours on hours of debugging. Send them this post, there is no need for a repo on this! Takes two seconds to setup and see it does not work.

1 Like

Bug is still here on 2019.4.1 LTS after 5 years.

1 Like

Hmm makes sense, but since I have an initialization scene, for me it works better to just call it on Start, I have no audio sources on this scene since it’s loaded right after a bootstrap scene - so there is no risk of something playing an audio for 1 frame or something weird like that.

In case some are still looking into this, the problem is not exactly with the SetFloat() of the AudioMixer as a few debug gave me the confirmation the the AudioMixer does indeed get the SetFloat() properly in its cache. The issue seems to be that the AudioMixer doesn’t update (set) the property during a certain internal phase of the Unity’s Awake() phase and simply skip it all alone if it is handled too soon. It’s kinda like if the AudioMixer has some sort of “warmup” phase where anything cached during the early part of the Awake() which make it skips anything thrown at it.

This could explains the kinda of hard-to-explain situation where, for some, the SetFloat() partially work.

As of this moment, the only way of properly avoiding this issues is to force the SetFloat() to be done after the Awake() one way or another. Be it by setting it through the Start() or a coroutine with a tiny bit of wait or with a Delay.

In case some are wondering, the problem is a per-scene issue as quick-switching scene doesn’t fix the problem.
Due to some double-layered checkup I set up in my project, a scene which is loaded twice doesn’t fix the issue.

To make it simple about what I’m writing about, it goes as this:
Scene B is launched. During the Awake() in Scene B, something is missing (a reference is not found) which force the game stop the script after loading Scene A which contain the references (set on an object with DontDestroyOnLoad()) and then the game returns automatically to Scene B. During the 2nd visit in Scene B, the Awake() is called again and, this time, goes further as the past-missing reference is now found, but the SetFloat() doesn’t get updated by the AudioMixer in the re-called Awake(). So, thinking about setting up a pre-load scene prior to your scene with the SetFloat() will mostly not work if it’s in the Awake(). Just saying from my tests.

2 Likes

Yeah it’s now 2021 this is my issue too…

slap a coroutine with WaitForNextFrame then SetFloat. All I can say is unity gave up on this one, So you gotta wait for one frame and then SetFloat

I am also facing this bug o Unity 2020.2.3f1

1 Like

This is “By Design” and won’t be fixed!

“As you can see the issue is resolved as By Design, meaning that this is expected behaviour for Unity. According to our developers “Awake is not the right place to apply the exposed values. This is because Awake gets called at many different times related to asset reloading in the editor slightly out of sync with the play state changes. On each play state, the editor will clear all exposed values, so this will override whatever values you applied in Awake(). You can easily fix this by moving your code to Start ()”.”

I really need this on Awake, so as a workaround made the Awake async and waited some time before setting the value.

public async Awake()
{
   await Task.Delay(TimeSpan.FromSeconds(0.01f));
   SetMixerValue();
}

So… i am seen it on unity 2020.3.2f1
I think the problem is the Snapshots, it has always minimum one and you can see it has a star.


When unity run it load the snapshot that have the star and set the values from it.

I think the execution order afects this because if you load a scene then load the scene that has the script that on awake change the values it works fine.

So another fix is load first a empty scene then it will work on awake.

2 Likes

Thanks for the above!

This works (I used this within my Main Menu)

using System.Threading.Tasks;

 private void Awake()
    {
        DelayedUpdateVolume();
    }
    async void DelayedUpdateVolume()
    {
        await Task.Delay(1);
        UpdateMixer();
    }

    void UpdateMixer() {
        float masterValue = PlayerPrefs.GetFloat("mastervolume");
        float soundValue = PlayerPrefs.GetFloat("volume");
        float musicValue = PlayerPrefs.GetFloat("volume2");
        audioMixer.SetFloat("mastervolume", masterValue);
        audioMixer.SetFloat("volume", soundValue);
        audioMixer.SetFloat("volume2", musicValue);
    }

My sliders are loaded first by LoadSettings() in the OnEnable.

2 Likes

I just spent 2 hours debugging and searching google for this, with zero results. It wasn’t until I googled SetFloat and Awake this finally showed up on the results. I wish they would fix this or at the very least, put it in the SetFloat() documentation!

2 Likes

Zohmygosh. It is 2022.
Seven years have gone by since this thread started.

Fortunately, moving my initialization to Start() is fine.

1 Like

This is just one more of those Unity’s pet bugs.

1 Like

Its simple. The mixer isn’t yet initialized by the time unity calls awake. So settings get overwritten.
Any of make a game? Then you know how many million lines of code goes into making this stuff. Cut them a break. I am here for the same problem, but I am not whining about it. I assume this was the issue and rather than plaguing an already busy company with my complaints, I will create my own work around. (Likely an enumerator that waits 1 second).

1 Like