Skip to content

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

Placeholder: the Audio Source component in the Properties panel, showing Clip, Gain, Pitch, Loop, Spatial and Play On Start

SettingWhat it does
ClipThe audio file to play
GainVolume. 1.0 is the file's own level; 0.5 is half
PitchPlayback speed and pitch together. 0.5 is an octave down and half speed, 2.0 an octave up and double
LoopStart again when it reaches the end
SpatialOn (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 StartStart 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

csharp
public class Enemy : GameEntity
{
    private AudioSourceComponent m_HitSound;

    protected override void OnCreate()
    {
        m_HitSound = GetComponent<AudioSourceComponent>();
    }

    public void TakeDamage()
    {
        m_HitSound.Play();
    }
}
MemberWhat it does
Play()Start playing from the beginning
Stop()Stop and reset to the start
Pause()Stop where it is; Play() resumes
IsPlayingWhether it's currently sounding
GainRead and set the volume
PitchRead and set the pitch
LoopSet 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:

csharp
Audio.MasterGain = 0.8f;

It's write-only, so pair it with a saved setting rather than reading it back:

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

csharp
m_HitSound.Play();
Input.RumbleGamepad(0, lowFreq: 0.7f, highFreq: 0.2f, durationMs: 150);

See also