Quick answer: The most common cause is passing 0 or a very small value as the timeToReach parameter in TransitionTo(). The time is in seconds, so TransitionTo(0f) means instant. Use a value like 1.0f for a one-second fade.

Here is how to fix Unity audio mixer snapshot not transitioning. You set up Audio Mixer snapshots for different game states—exploration, combat, underwater, menu—and call TransitionTo() to blend between them. But instead of a smooth fade, the audio cuts abruptly from one snapshot to another. Or worse, the snapshot transition seems to do nothing at all and the audio stays stuck on the previous settings. This guide covers every reason snapshot transitions fail and how to get smooth, reliable audio blending.

How Audio Mixer Snapshots Work

An Audio Mixer Snapshot stores a complete set of parameter values for an Audio Mixer—volumes, pitches, effect settings, send levels. When you call snapshot.TransitionTo(timeToReach), Unity interpolates from the current parameter values to the snapshot’s values over the specified time in seconds.

Snapshots do not crossfade audio clips. They crossfade mixer parameters. If you have a Music group at -10 dB in one snapshot and -80 dB in another, TransitionTo(2f) will smoothly ramp the volume from -10 to -80 over two seconds. The interpolation is linear in the parameter space (which is decibels for volume).

Solution 1: Use the Correct TransitionTo Time

The most common mistake is passing 0 or a very small value as the transition time, or calling TransitionTo() repeatedly every frame.

using UnityEngine;
using UnityEngine.Audio;

public class AudioSnapshotManager : MonoBehaviour
{
    [SerializeField] private AudioMixerSnapshot explorationSnapshot;
    [SerializeField] private AudioMixerSnapshot combatSnapshot;
    [SerializeField] private float transitionTime = 1.5f;

    private AudioMixerSnapshot currentSnapshot;

    // WRONG: Calling TransitionTo every frame restarts the transition
    // void Update()
    // {
    //     if (inCombat) combatSnapshot.TransitionTo(transitionTime);
    // }

    // CORRECT: Call TransitionTo once when state changes
    public void EnterCombat()
    {
        if (currentSnapshot == combatSnapshot) return;

        currentSnapshot = combatSnapshot;
        combatSnapshot.TransitionTo(transitionTime);
        Debug.Log($"Transitioning to combat audio over {transitionTime}s");
    }

    public void ExitCombat()
    {
        if (currentSnapshot == explorationSnapshot) return;

        currentSnapshot = explorationSnapshot;
        explorationSnapshot.TransitionTo(transitionTime);
        Debug.Log($"Transitioning to exploration audio over {transitionTime}s");
    }
}

The transitionTime parameter is in seconds. A value of 0 means instant. Values between 0.5 and 3.0 seconds work well for most game state transitions. For subtle ambient changes, use longer times (3–5 seconds). For dramatic shifts like entering water, shorter times (0.3–0.8 seconds) feel more responsive.

Solution 2: Fix Exposed Parameter Conflicts

If you set Audio Mixer parameters via SetFloat() in code, those values conflict with snapshot transitions. When a snapshot transition runs, it overwrites all parameters—including ones you set manually. This means your SetFloat() calls get undone.

using UnityEngine;
using UnityEngine.Audio;

public class AudioVolumeController : MonoBehaviour
{
    [SerializeField] private AudioMixer mixer;
    [SerializeField] private AudioMixerSnapshot defaultSnapshot;

    // Exposed parameter names (must match exactly what's in the Audio Mixer)
    private const string MUSIC_VOLUME = "MusicVolume";
    private const string SFX_VOLUME = "SFXVolume";

    public void SetMusicVolume(float linearVolume)
    {
        // Convert linear 0-1 to decibels (-80 to 0)
        float dB = linearVolume > 0.0001f
            ? Mathf.Log10(linearVolume) * 20f
            : -80f;

        // This works, but will be overridden by any active snapshot transition
        bool success = mixer.SetFloat(MUSIC_VOLUME, dB);

        if (!success)
        {
            Debug.LogError($"Failed to set '{MUSIC_VOLUME}'. " +
                "Is the parameter exposed? Right-click it in the Audio Mixer " +
                "and select 'Expose to script'.");
        }
    }

    // Read the current value to verify it was set
    public float GetMusicVolume()
    {
        float dB;
        mixer.GetFloat(MUSIC_VOLUME, out dB);
        return Mathf.Pow(10f, dB / 20f);
    }
}

To avoid this conflict, either use snapshots exclusively for audio state management, or use SetFloat() exclusively. Mixing both approaches leads to unpredictable behavior where snapshots overwrite your manual settings.

Solution 3: Blend Multiple Snapshots with Weights

For complex audio environments where you need to mix multiple states simultaneously—for example, 60% exploration and 40% cave ambience—use TransitionToSnapshots() (plural) with weight arrays.

using UnityEngine;
using UnityEngine.Audio;

public class AudioEnvironmentBlender : MonoBehaviour
{
    [SerializeField] private AudioMixer mixer;
    [SerializeField] private AudioMixerSnapshot outdoorSnapshot;
    [SerializeField] private AudioMixerSnapshot caveSnapshot;
    [SerializeField] private AudioMixerSnapshot underwaterSnapshot;
    [SerializeField] private float blendSpeed = 2f;

    private float[] targetWeights = new float[] { 1f, 0f, 0f };
    private float[] currentWeights = new float[] { 1f, 0f, 0f };

    private AudioMixerSnapshot[] snapshots;

    void Start()
    {
        snapshots = new[] { outdoorSnapshot, caveSnapshot, underwaterSnapshot };
    }

    public void SetEnvironment(float outdoor, float cave, float underwater)
    {
        // Weights must sum to 1.0
        float total = outdoor + cave + underwater;
        targetWeights[0] = outdoor / total;
        targetWeights[1] = cave / total;
        targetWeights[2] = underwater / total;
    }

    void Update()
    {
        // Smoothly interpolate current weights toward target weights
        bool changed = false;
        for (int i = 0; i < currentWeights.Length; i++)
        {
            float newWeight = Mathf.MoveTowards(currentWeights[i], targetWeights[i],
                blendSpeed * Time.deltaTime);

            if (Mathf.Abs(newWeight - currentWeights[i]) > 0.001f)
            {
                currentWeights[i] = newWeight;
                changed = true;
            }
        }

        if (changed)
        {
            // Apply the blended snapshot weights immediately (0 transition time)
            mixer.TransitionToSnapshots(snapshots, currentWeights, 0f);
        }
    }
}

This approach gives you frame-by-frame control over the audio blend. It is ideal for environments where the player can be partially in one zone and partially in another—for example, standing at the mouth of a cave with one ear in and one ear out.

Solution 4: Verify Mixer Group Routing

If a snapshot transition runs but certain sounds are not affected, the issue may be that those Audio Sources are not routed through the mixer group that the snapshot controls. Every Audio Source must have its Output set to a mixer group for snapshots to affect it.

using UnityEngine;
using UnityEngine.Audio;

public class AudioRoutingValidator : MonoBehaviour
{
    [SerializeField] private AudioMixerGroup expectedGroup;

    void Start()
    {
        // Find all AudioSources in the scene
        AudioSource[] allSources = FindObjectsByType<AudioSource>(FindObjectsSortMode.None);

        foreach (AudioSource source in allSources)
        {
            if (source.outputAudioMixerGroup == null)
            {
                Debug.LogWarning($"AudioSource on '{source.gameObject.name}' has no mixer group. " +
                    "It will not be affected by mixer snapshots.", source);
            }
        }
    }

    // Assign a mixer group to an AudioSource at runtime
    public static void RouteToGroup(AudioSource source, AudioMixerGroup group)
    {
        source.outputAudioMixerGroup = group;
    }
}

Audio Sources with no output group go directly to the system audio output and bypass the mixer entirely. Make it a habit to always assign an output group when creating Audio Sources, whether in the Inspector or via code.

“Audio Mixer snapshots are powerful but unforgiving. Call TransitionTo once, not every frame. Do not mix SetFloat and snapshots for the same parameters. Route every Audio Source through a mixer group. Get these three things right and snapshots work beautifully.”

Related Issues

If your Audio Mixer works in the editor but sounds different in builds, see Fix: Unity Audio Mixer Build Differences. For issues where audio clips do not play at all, check Fix: Unity AudioSource Not Playing. To collect audio bug reports from players with specific hardware configurations, read Bug Reporting Tools for Unity Developers.

Call TransitionTo once per state change, not every frame. Use decibel conversion for volume (Mathf.Log10 * 20). Do not mix SetFloat and snapshot transitions on the same parameters. Route all Audio Sources through mixer groups. Test snapshot transitions in builds, not just the editor.