Audio
Sound effects, music and ambience — attached to entities so they can be positioned in the world, or flat for anything that shouldn't be.
The two components
Audio Source is the thing that makes noise. Add one with Add Component → General → Audio Source, then assign a clip. Supported formats are .wav, .mp3 and .ogg.
Audio Listener is the ear. Add one with Add Component → General → Audio Listener and put it on whatever should hear the world — usually the player, or the camera. If your scene has no listener at all, audio falls back to following the primary camera, so a simple game works without you adding one.
Only one listener
Primary isn't enforced — if two entities both claim it, the first one found wins, which is rarely the one you meant. Keep it to one.
Audio Source settings
| Setting | What it does |
|---|---|
| Clip | The audio file to play |
| Gain | Volume. 1.0 is the file's own level; 0.5 is half |
| Pitch | Playback speed and pitch together. 0.5 is an octave down and half speed, 2.0 an octave up and double |
| Loop | Start again when it reaches the end |
| Spatial | On (the default): the sound is positioned in the world and gets quieter with distance. Turn it off for music, narration and UI clicks — anything that shouldn't move when the player does |
| Play On Start | Start playing when the scene starts, rather than waiting for a script |
There's a Preview button next to the clip so you can hear it without entering Play mode, and the clip's duration is shown beside it.
Music with Spatial left on
This is the most common audio complaint, and it isn't a bug: a music track on a spatial source is a sound sitting at a point in your level, so it fades as the player walks away from wherever that entity happens to be. Turn Spatial off for music.
Playing sounds from a script
public class Enemy : GameEntity
{
private AudioSourceComponent m_HitSound;
protected override void OnCreate()
{
m_HitSound = GetComponent<AudioSourceComponent>();
}
public void TakeDamage()
{
m_HitSound.Play();
}
}| Member | What it does |
|---|---|
Play() | Start playing from the beginning |
Stop() | Stop and reset to the start |
Pause() | Stop where it is; Play() resumes |
IsPlaying | Whether it's currently sounding |
Gain | Read and set the volume |
Pitch | Read and set the pitch |
Loop | Set looping on or off |
Loop is write-only — you can turn it on and off from a script, but you can't read back what it's set to. Keep the value in your own field if you need to know.
These calls are Play-mode only, and they work whether or not the source has ever played before — a source with Play On Start off, or one whose clip was only ever assigned from a script, both just work.
Master volume
One global knob scales every sound in the game — exactly what a settings slider wants:
Audio.MasterGain = 0.8f;It's write-only, so pair it with a saved setting rather than reading it back:
private void ApplyVolume(float v)
{
Audio.MasterGain = v;
Settings.SetFloat("audio.master", v);
Settings.Save();
}
protected override void OnCreate()
{
Audio.MasterGain = Settings.GetFloat("audio.master", 1.0f);
}See Saving and settings for how Settings persists across sessions.
Long clips stream, short ones don't
Sound effects are decoded once and kept in memory so they play instantly. Music and ambience are streamed from disk in small chunks on a background thread, so a three-minute track costs a small buffer rather than the tens of megabytes it would take fully decoded.
The engine picks between them by duration — under about two seconds is decoded, longer is streamed. You can override it per file: select the audio in the Content Browser and change the streaming setting in Import Settings. Force decoding for a long clip that has to start with zero latency; force streaming for a short one you only ever play once.
Pausing
Audio pauses with the world. When you pause your game by setting Time.TimeScale to 0, spatial gameplay audio stops with everything else; a music source keeps going unless you stop it yourself, which is usually what you want behind a pause menu.
On mobile, audio stops when the app goes to the background and resumes when it comes back — you don't have to handle that.
Sound and feel together
Impacts land harder with a matching rumble. See Input for rumble and .jhaptic curves, and note that haptics have their own intensity setting so a player can mute vibration without muting sound.
m_HitSound.Play();
Input.RumbleGamepad(0, lowFreq: 0.7f, highFreq: 0.2f, durationMs: 150);See also
- Saving and settings — persisting volume preferences
- Scenes — what happens to audio across a scene change
- Performance — measuring what audio costs you in memory