# 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.