Quick answer: Spatial Blend defaults to 0 (2D). At 0, distance does not attenuate. Move the Spatial Blend slider on the AudioSource to 1 for full 3D, then configure Min Distance, Max Distance, and the Volume Rolloff curve in the 3D Sound Settings section. Set dopplerLevel = 0 if pitch shifts unexpectedly.

Here is how to fix Unity 3D AudioSources that refuse to attenuate with distance. You imported an AudioClip, attached an AudioSource to a ticking clock GameObject, and walked 50 meters away. The clock ticks at full volume like you are standing next to it. This is almost always the Spatial Blend slider sitting at 0 (pure 2D). Every new AudioSource defaults this way and it catches everyone who is not paying attention.

The Symptom

What Causes This

Spatial Blend defaults to 0. The AudioSource Inspector has a Spatial Blend slider in the 3D Sound Settings section. 0 means the sound is 2D (UI, music) and plays at uniform volume. 1 means fully 3D (attenuates with distance, pans based on position). The default is 0, which catches everyone expecting 3D behavior out of the box.

Min Distance too large. Within Min Distance from the listener, volume is at full. If Min Distance is 500 and your scene is 100 meters wide, the listener is always inside Min Distance and the sound is always full-volume. Default Min Distance is 1; Max Distance is 500. Tune to your scene scale.

Rolloff curve flat. If someone edited the Volume Rolloff curve to a flat line, distance has no effect. The default Logarithmic curve drops off rapidly within Min Distance. A custom curve might have been flattened by accident.

AudioListener absent or duplicated. Each scene needs exactly one AudioListener. No listener = no audio at all. Multiple listeners produce unpredictable volume — Unity picks one arbitrarily. Check the scene for AudioListener components.

Using PlayClipAtPoint incorrectly. AudioSource.PlayClipAtPoint creates a temporary AudioSource with default 3D settings — and the default is 2D! So PlayClipAtPoint sounds are often non-attenuating by default. Use a pool of configured AudioSources instead.

The Fix

Step 1: Set Spatial Blend to 1. On the AudioSource component, find the Spatial Blend slider. Drag all the way to the right (1.0). Or set in code:

using UnityEngine;

public class SoundConfig : MonoBehaviour
{
    void Awake()
    {
        AudioSource src = GetComponent<AudioSource>();
        src.spatialBlend = 1f; // fully 3D
        src.minDistance = 2f;
        src.maxDistance = 30f;
        src.rolloffMode = AudioRolloffMode.Logarithmic;
    }
}

For gameplay sounds (footsteps, ambient loops, enemy noises), Spatial Blend should be 1. For UI sounds (button clicks, menu chimes) and background music, keep at 0.

Step 2: Configure Min/Max Distance for your scale. Rule of thumb: Min Distance is “sound is at full volume within this radius,” Max Distance is “sound is inaudible at this distance.”

Step 3: Choose the right rolloff mode. Logarithmic is realistic — loud very close, falls off quickly, tail goes out to max. Linear is predictable for gameplay — proportional fade from min to max. Custom Rolloff lets you edit the curve directly; useful for designer-tuned falloff.

// set a custom rolloff curve
AnimationCurve curve = new AnimationCurve(
    new Keyframe(0f, 1f),
    new Keyframe(0.5f, 0.3f),
    new Keyframe(1f, 0f)
);
src.SetCustomCurve(AudioSourceCurveType.CustomRolloff, curve);

Step 4: Verify AudioListener placement. The AudioListener component is usually on the Main Camera. For first-person or third-person games with moving cameras, confirm the listener is where you expect the “ears” to be. For top-down games, some projects place the listener on the player character instead.

Check for duplicates via a scene-wide component search:

using UnityEditor;
using UnityEngine;

public static class ListenerCheck
{
    [MenuItem("Tools/Count AudioListeners")]
    public static void Check()
    {
        var listeners = Object.FindObjectsOfType<AudioListener>();
        Debug.Log($"Found {listeners.Length} AudioListeners");
    }
}

Step 5: Manage Doppler. Doppler Level defaults to 1. For realistic moving sounds (vehicles, projectiles) keep it at 1 — it pitches sounds based on relative velocity. For stationary or teleporting sounds, set to 0 to prevent artifacts.

src.dopplerLevel = 0f; // disable Doppler for static/teleporting sources

Avoiding PlayClipAtPoint Pitfalls

PlayClipAtPoint is a convenience method that spawns a throwaway AudioSource. It uses defaults — Spatial Blend 0, no attenuation. For 3D one-shot sounds, roll your own:

public static void Play3DOneShot(AudioClip clip, Vector3 position, float volume = 1f)
{
    GameObject go = new GameObject("OneShot");
    go.transform.position = position;
    AudioSource src = go.AddComponent<AudioSource>();
    src.clip = clip;
    src.volume = volume;
    src.spatialBlend = 1f;
    src.minDistance = 2f;
    src.maxDistance = 30f;
    src.Play();
    Object.Destroy(go, clip.length);
}

Better yet, pool AudioSources rather than allocating GameObjects per sound. GameObject allocation during gameplay causes GC hitches.

Debugging

Window > Audio Mixer. Enable Edit in Play Mode. Watch the Master channel levels. If a sound is audible when it should be silent, trace back through submixes to find which source is feeding it. Right-click the AudioSource in Hierarchy during Play Mode > Inspector shows current volume, attenuation factor, and distance to listener.

“Spatial Blend 0 is the most confusing default in the Unity Inspector. Half of every team has been bitten by it.”

Audio Mixer Snapshots

For global volume control across many 3D sources, route them to an AudioMixer group and adjust the group’s level. Distance attenuation and mixer attenuation compose — a sound at 50% attenuation through distance plus a mixer at 50% gives 25% final volume.

For related audio issues, see Unity Audio Crackling or Popping.

Spatial Blend = 1. Min/Max to scene scale. Logarithmic rolloff unless you need otherwise. Doppler off for teleports.