Summary
AudioSource is the Unity component that plays audio. It is attached to a GameObject and references an AudioClip asset. For sound effects, the primary method is PlayOneShot, which plays a clip once without interrupting other sounds already playing on the same source. For background music, AudioSource.Play() combined with loop = true is standard. For transient world-positioned sounds (a coin collected, an enemy defeated), the static AudioSource.PlayClipAtPoint plays at a location without requiring an AudioSource on the emitting object.
Key ideas
AudioSource.Play() — plays the assigned clip from the beginning. If called again while playing, it restarts. Use for background music, ambient loops, and single persistent sounds.
AudioSource.PlayOneShot(clip) — plays the given clip once without replacing any currently playing sound on that source. Multiple calls layer on top of each other. Use for sound effects that may fire in rapid succession (coins, footsteps, hits).
AudioSource.PlayClipAtPoint(clip, worldPosition) — static method; no AudioSource component needed on the caller. Spawns a temporary GameObject at the given world position, plays the clip, then destroys itself. Use for pickups, explosions, and any transient world sound.
Looping background music: Set clip, loop = true, volume, then call Play(). Use a dedicated AudioSource component for music — separate from the one used for SFX — so volume can be controlled independently.
AudioListener.volume — a static property (0 to 1) that scales all audio in the game. Setting it to 0f mutes everything; 1f is full volume.
[Range(0f, 1f)] — an Inspector attribute that displays a float field as a slider constrained to the given range. Useful for volume controls.
Mathf.Clamp01(value) — shorthand for Mathf.Clamp(value, 0f, 1f). Use when accepting a volume value from outside code.
In practice
Looping background music:
[Header("Music")]
[SerializeField] private AudioSource musicSource;
[SerializeField] private AudioClip mainTheme;
[SerializeField] [Range(0f, 1f)] private float musicVolume = 0.4f;
private void StartMusic()
{
if (musicSource == null || mainTheme == null) return;
musicSource.clip = mainTheme;
musicSource.loop = true;
musicSource.volume = musicVolume;
musicSource.Play();
}SFX with PlayOneShot (layers, does not interrupt):
[Header("SFX")]
[SerializeField] private AudioSource sfxSource;
[SerializeField] private AudioClip coinClip;
[SerializeField] private AudioClip hitClip;
private void PlaySFX(AudioClip clip)
{
if (clip == null || sfxSource == null) return;
sfxSource.PlayOneShot(clip); // layered — rapid calls don't interrupt
}
// Usage
PlaySFX(coinClip);
PlaySFX(hitClip);PlayClipAtPoint — world-positioned sound, no AudioSource needed:
public void OnCoinCollected(Vector3 worldPosition)
{
if (coinClip != null)
AudioSource.PlayClipAtPoint(coinClip, worldPosition);
}Global mute toggle:
private bool isMuted = false;
public void ToggleMute()
{
isMuted = !isMuted;
AudioListener.volume = isMuted ? 0f : 1f;
}Adjustable music volume:
public void SetMusicVolume(float volume)
{
musicVolume = Mathf.Clamp01(volume);
if (musicSource != null)
musicSource.volume = musicVolume;
}Recommended setup
For a typical 2D game:
- Music AudioSource — on the FeedbackManager or a dedicated MusicManager.
Loop = true,Play On Awake = trueoptional. Volume set in script. - SFX AudioSource — same GameObject as above, or on the player. Used with
PlayOneShotonly. Clip field left empty. - Transient world sounds — handled by
AudioSource.PlayClipAtPoint; no component required on pickups or enemies.
There is no need for a separate AudioSource on every pickup or hazard. Centralising sound playback in a FeedbackManager keeps scene setup simple and makes volume control straightforward.
Gotchas
AudioSource.Play()restarts the clip from the beginning each call. If a coin collection sound is called multiple times per second, only the last call will be audible. UsePlayOneShotfor any effect that can trigger rapidly.PlayClipAtPointcreates a temporary GameObject. It is self-cleaning, but generates a small allocation per call. Acceptable for occasional events; avoid using it every frame.- If no
AudioListenerexists in the scene (usually on the Main Camera), Unity logs a warning and no sound plays. Check the Camera has anAudioListenercomponent. AudioSource.PlayOneShotdoes not support volume scaling beyond the source’s ownvolumeproperty. To play a specific clip at a different volume, pass the volume as the second argument:sfxSource.PlayOneShot(clip, 0.5f).
Related
- unity-particle-system-scripting — particles and audio are typically triggered together as game feedback
- unity-inspector-references — wiring AudioSource and AudioClip references
- monobehaviour-lifecycle —
Startfor initialising music;Updatefor volume fades if needed - audio-middleware-overview — where teams move when simple AudioSource playback is no longer enough for adaptive music or runtime mixing