# 1. 3D AudioSource Settings Part of [[Spatial Audio and Reverb Zones]]. Next: [[2. Reverb Zones and Mixer Effects]]. > [!note] Verification status > Property meanings checked 2026-11-08 against the 6000.5 `AudioSource` scripting reference and the Audio Source component reference: `spatialBlend` 0 = full 2D, 1 = full 3D; `priority` 0 most important, 256 least, default 128; `reverbZoneMix` linear 0..1 with extra headroom from 1..1.1 (up to +10 dB) for near-field/distant tricks; `spread` is the speaker-space spread angle of a 3D stereo or multichannel sound; `dopplerLevel` scales Doppler; `rolloffMode` / `minDistance` / `maxDistance` control attenuation; `bypassReverbZones` skips reverb zones. **None of the code has been compiled or play-tested in Unity.** ## 1.1 The listener is the microphone An `AudioSource` does nothing spatial until an `AudioListener` exists to hear it. The listener is usually on the camera (or, in VR, on the XR origin / center-eye so it follows the player's head). Two listeners in one scene is a common mistake - Unity will warn and one of them will "win." For Quest, the listener should move with the head, not with a body proxy at waist height, or footsteps and head-relative panning will disagree. `AudioListener.volume` is a global scalar; `AudioListener.pause` pauses sources except those with `ignoreListenerPause = true` (already used for pause-menu UI in [[2. Audio Mixer Snapshots and Exposed Parameters]]). `bypassListenerEffects` on a source ignores global listener filters. The 6000.5 reference also notes that listener effects do not apply when the source plays into a mixer group - another reason music routed to `Music/Bed` does not pick up a listener-wide low-pass you might have added for underwater. Underwater on SFX is a snapshot; underwater on a world emitter can be a reverb zone plus a low-pass. Do not pile both on blindly. ## 1.2 The settings that actually change what you hear | Property | Why it exists | Practical starting point | |---|---|---| | `spatialBlend` | 0 = stereo as authored (HUD, score, car-interior radio); 1 = full 3D; in between is a blend | 0 for [[Music Mood Mixer]] stems and most UI; 1 for world interactables, enemies, boomboxes; 0.15-0.3 for a car dash you still want slightly "in the cabin" | | `rolloffMode` | How level falls with distance: Logarithmic (default, roughly physical), Linear, Custom | Logarithmic for most props; Custom when a voice should stay intelligible across a room then drop quickly | | `minDistance` | Inside this radius the source does not get louder | 1 m for a person talking; larger for a PA speaker | | `maxDistance` | Where attenuation ends (silence or floor, depending on rolloff) | Tight on Quest (see Part 4); generous on desktop interiors | | `dopplerLevel` | Pitch shift from relative velocity | 1 is often cartoonish on footsteps; 0 for UI and dialogue; small (0.2-0.5) for vehicles and bullets | | `spread` | Speaker-space width of a 3D stereo/multichannel clip (degrees) | 0 for a point source (a bee); wider for a river or crowd you authored as stereo | | `priority` | Who gets a real voice when the cap is hit | 0 music; ~64 dialogue; 128 default SFX; 200+ decorative ambience | | `reverbZoneMix` | How much of this source enters the zone reverb | 1 for most world emitters; 0 for dry UI and for radio that should not pick up the cave; 1..1.1 if you need up to +10 dB of extra send | | `bypassReverbZones` | Ignore zones entirely | On for the adaptive score and usually for UI | | `spatialize` | Enable a *custom spatializer plugin* (HRTF etc.) | Only works if a plugin is installed and selected; otherwise setting it true warns (see Part 3) | | `outputAudioMixerGroup` | Where the voice goes after spatialization | Still route world SFX to `SFX/World` or `SFX/Interactables` from [[Audio Mixers and Character Audio]] | `panStereo` only applies to 2D (or the 2D portion of a blend) mono/stereo clips. Do not use it to fake 3D. Unity needs a **mono** (or at least not already-baked-binaural) clip to spatialize convincingly. A stereo file already contains its own left/right image; at `spatialBlend = 1` Unity will still place it, but you are fighting an image that was authored in speakers. Meta's spatialize page is explicit for their plugin: "It is important that all sounds passed to Meta XR Audio are monophonic." That advice is good even when you are on Unity's built-in panner. ## 1.3 A spatial profile asset (Type Object) The same way footsteps banks and radio stations are assets, spatial behaviour should not be twenty inspectors with slightly different max distances. ```csharp using UnityEngine; [CreateAssetMenu(menuName = "Audio/Spatial Audio Profile", fileName = "Spatial_")] public class SpatialAudioProfile : ScriptableObject { [Range(0f, 1f)] public float spatialBlend = 1f; public AudioRolloffMode rolloffMode = AudioRolloffMode.Logarithmic; public float minDistance = 1f; public float maxDistance = 25f; [Range(0f, 5f)] public float dopplerLevel = 0f; [Range(0f, 360f)] public float spread = 0f; [Range(0, 256)] public int priority = 128; [Range(0f, 1.1f)] public float reverbZoneMix = 1f; public bool bypassReverbZones = false; public bool spatialize = false; public bool spatializePostEffects = false; public bool bypassEffects = false; } public static class SpatialAudioProfileExtensions { public static void ApplyTo(this SpatialAudioProfile profile, AudioSource src) { if (profile == null || src == null) return; src.spatialBlend = profile.spatialBlend; src.rolloffMode = profile.rolloffMode; src.minDistance = profile.minDistance; src.maxDistance = profile.maxDistance; src.dopplerLevel = profile.dopplerLevel; src.spread = profile.spread; src.priority = profile.priority; src.reverbZoneMix = profile.reverbZoneMix; src.bypassReverbZones = profile.bypassReverbZones; src.spatialize = profile.spatialize; src.spatializePostEffects = profile.spatializePostEffects; src.bypassEffects = profile.bypassEffects; } } ``` ```csharp using UnityEngine; using UnityEngine.Audio; /// Applies a SpatialAudioProfile in Awake and optionally assigns a mixer group. [RequireComponent(typeof(AudioSource))] public class SpatialAudioSourceSetup : MonoBehaviour { [SerializeField] SpatialAudioProfile profile; [SerializeField] AudioMixerGroup mixerGroup; [SerializeField] bool applyEveryPlay = false; AudioSource _src; void Awake() { _src = GetComponent<AudioSource>(); Apply(); } void OnEnable() { if (applyEveryPlay) Apply(); } public void Apply() { if (mixerGroup != null) _src.outputAudioMixerGroup = mixerGroup; profile.ApplyTo(_src); } } ``` > [!warning] Code not compiled in Unity > Not compiled. Suggested assets: `Spatial_Dialog` (blend 1, max 18 m, priority 64, no Doppler), `Spatial_Prop` (blend 1, max 20 m, priority 128), `Spatial_Vehicle` (blend 1, some Doppler, larger minDistance), `Spatial_Score` (blend 0, bypass reverb zones, priority 0), `Spatial_Boombox` (blend 1, custom rolloff that stays audible across a room). Apply `Spatial_Prop` on pooled emitters in [[2. Pooled AudioSource Service]] so a reused source cannot leak the last boombox's maxDistance (that leak is already called out in [[4. Interactable Audio Pitfalls and Quest]]). If you need a custom rolloff curve, `AudioSource.SetCustomCurve(AudioSourceCurveType.CustomRolloff, curve)` is the scripting hook (`GetCustomCurve` reads it back). The component reference's 3D sound settings panel is the authoring UI. Verify curve behaviour in the Editor rather than assuming a particular default shape beyond Logarithmic vs Linear vs Custom. ## 1.4 Doppler and moving listeners `dopplerLevel` uses the relative velocity between source and listener. For physics objects, that velocity comes from the Rigidbody ([[Physics 3D]]). For a `CharacterController` there is no Rigidbody velocity unless you feed one; a huge `dopplerLevel` on player footsteps usually sounds like a tape machine, which is why the table above starts at 0. In VR the *listener* moves every frame with the head. Even a static emitter can Doppler if the player leans quickly and `dopplerLevel` is high. Prefer 0 on Quest dialogue and interactables unless you have a specific vehicle or projectile you want to hear "pass by." Part 2 puts those 3D voices into rooms that sound like rooms.