How to Play Sound Effects in Unity

by Lance Gold

Adding audio clips to Unity game objects can be done in a few different ways.

Return to index

Decide when you want a connected audio clip to sound.

Method One: no AudioClip reference variable

AudioSource.Play

Description: Plays the clip.

From the Unity Scripting API

Start with declaring a reference variable to hold the gameObject of type AudioSource


using UnityEngine;

public class Player : MonoBehaviour
{
...
    [SerializeField]
    private AudioSource _lazerShot;
...
}

Save and open Unity Editor.

Add an Audio Source component to Player. Drag and drop the audio controller (type AudioSource) from the Assets — Audio — laser_shot to Player —Audio Source — AudioClip. Uncheck the “Play on Awake” parameter.

Drag audio clip from Assets to Audio Source

Drag audio clip from Assets to Audio Source

Save. In the Player script, assign the reference


public class Player : MonoBehaviour
{
...
   void Start()
    {
...
        _lazerShot = GetComponent();
    }
}

Use the AudioSource.play() method


public class Player : MonoBehaviour
{
...
    void FireLaser()
    {
...
        _lazerShot.Play();
    }
}

Save.

Method Two uses an AudioSource and an AudioClip and “Play on Awake” is Unchecked

Clip is the music, from Assets. Source is the controller, from Add Component.

From the online tutorial


using UnityEngine;

public class Player : MonoBehaviour
{
...
   [SerializeField]
   private AudioClip _lazerSoundShot;
   private AudioSource _audioSource;

Add Component to the Player object.

Player with Audio Source component

Player with Audio Source component

Uncheckmark “Play On Awake” when the audio is connected to the end of an object’s life.

Assign the reference variable _audioSource using GetComponent() so to check if null, instead of [SerializeField].

Leave the AudioClip parameter unassigned as “None (Audio Clip).” The reference variable “_lazerSoundShot” holds the Assets — Audio — laser_shot.

Additional assets can be dragged into additional reference variables, and then called with AudioSource.clip().


    [SerializeField]
    private AudioClip _lazerSoundShot;
    private AudioSource _audioSource;


    // Start is called before the first frame update
    void Start()
    {
        _audioSource = GetComponent();

        if( _audioSource == null )
        {
            Debug.LogError("AudioSource on the player is null.");
        } else
        {
            _audioSource.clip = _lazerSoundShot; // Editor shows none until Start()
        }
...
    }

Do drag and drop the lazer_shot to the Player (Script) variable “_lazerSoundShot.”

Drag audio clip to reference variable

Drag audio clip to reference variable

Now use AudioSource.Play() as needed


public class Player : MonoBehaviour
{
...
    void FireLaser()
    {
...
        _audioSource.Play();
    }
}

Save.

Method Three — Call Sound as needed from a Manager Class

Move parameters and variables to a new Script AudioManager. Access variables using public methods. Access Parameters using GetComponent<>().

New AudioManager script

New AudioManager script

Highlight Hierarchy — Game — Audio_Manager and drag and drop script as a new component.

For the child Background — AudioSource, Parameter “Play On Awake” is checked.

For the parent Audio_Manager — AudioSource — Play On Awake is uncheckmarked.

Audio Manager (Script) as added component to Hierarchy — Audio_Manager

Audio Manager (Script) as added component to Hierarchy — Audio_Manager

Save. Wait. Double click on the script to open in Visual Studio

First migrate variables from other classes.


using UnityEngine;

public class AudioManager : MonoBehaviour
{
    [SerializeField]
    private AudioClip _explosionSound;
    [SerializeField]
    private AudioClip _lazerSoundShot;

    private AudioSource _audioSource;
}

Drag and drop Assets — Audio — audioclips into variable references in the Unity Editor.

Drag Audio clips to Reference Variables in Audio Manager (Script)

Drag Audio clips to Reference Variables in Audio Manager (Script)

Migrate existing methods into the new script.


public class AudioManager : MonoBehaviour
{
...
   private AudioSource _audioSource;
   void Start()
    {
        _audioSource = GetComponent();

        if (_audioSource == null)
        {
            Debug.LogError("AudioSource on the player is null.");
        }
    }
}

Create public methods to SoundSource.Play() clips.


public class AudioManager : MonoBehaviour
{
...
    public void PlayLazerSound()
    {
        if (_audioSource)
        {
            _audioSource.clip = _lazerSoundShot;
            _audioSource.Play();
        }
    }
    public void PlayExplosionSound()
    {
        if( _audioSource )
        {
            _audioSource.clip = _explosionSound;
            _audioSource.Play();
        }
    }
}

Save.

Access AudioManager class methods from outside scripts


using UnityEngine;
public class Player : MonoBehaviour
{
...
    private AudioManager _audioManager;
    void Start()
    {
...
        _audioManager = GameObject.Find("Audio_Manager").GetComponent();
        if ( _audioManager == null )
        {
            Debug.LogError("AudioManager._audioManager is null.");
        }
    }

    void FireLaser()
    {
...
        if( _audioManager )
        {
            _audioManager.PlayLazerSound();
        }
    }

Save.

Three Objects, yet one Script and one Audio Clip

The bonus power boost object hits a player. Boost object disappears. Player object remains. Add the Audio Source and Audio Clip to the Player object.


using UnityEngine;

public class PowerUp : MonoBehaviour
{
...
    private void OnTriggerEnter2D(Collider2D other)
    {
        if(other.tag == "Player")
        {
            // communicate with the player script, through other
            Player player = other.transform.GetComponent();
            if (player != null)
            {
                switch (_powerupID)
                {
                    case 0:
                        player.TripleShotActive(); // in script Player.cs
                        break;
                    case 1:
                        player.SpeedBoostActive(); // also in Player.cs
                        break;
                    case 2:
                        player.ShieldsActive();  // also in Player.cs
                        break;
                    default:
                        ;
                        break;
                }
            }

            Destroy(this.gameObject);
        }
    }
}

Method One: Use the surviving gameObject

Here is the Player class with added second reference variable:


public class Player : MonoBehaviour
{
...
    // reference variable to store audio clip
    [SerializeField]
    private AudioClip _laserSoundClip, _powerUpSoundClip;
    private AudioSource _audioSource;
...
    public void TripleShotActive()
    { ... }
    public void SpeedBoostActive()
    { ... }
    public void ShieldsActive()
    { ... }
...
}

(a) Add Component “Audio Source” to just the Player gameObject.

(b) create one reference variable for the one Source and one Clip.

(c) Highlight Player and drag and drop the power_up_sound clip into the Inspector — Player (Script) variable.

(d) Uncheckmark the “Is Looping” in the Audio Source.

(e) Add code in Script — additional method “SoundAudioClipNoise().”

Drag power_up_sound into reference in Player (Script)

Drag power_up_sound into reference in Player (Script)

Here is the _audioSource assignment (already there from a previous something):


using UnityEngine;

public class Player : MonoBehaviour
{
...
    private AudioSource _audioSource;
    void Start()
    {
...
        // find gamecomponent and assign type
        _audioSource = GetComponent();

            if ( _audioSource == null )
        {
            Debug.LogError("AudioSource is missing.");
        }
    }
...
}

Add the new method:


using UnityEngine;

public class Player : MonoBehaviour
{
...
    [SerializeField]
    private AudioClip _powerUpSoundClip; // connected to PowerUp using Unity editor
    private AudioSource _audioSource;

    public void PlayPowerUpSoundClip()
    {
        _audioSource.clip = _powerUpSoundClip;
        _audioSource.Play();
    }
}

Add the method call, save, test:


using UnityEngine;
public class Player : MonoBehaviour
{
...
    public void PlayPowerUpSoundClip()
    {
        _audioSource.clip = _powerUpSoundClip;
        _audioSource.Play();
// old version removed:       _audioSource.clip = _laserSoundClip;
    }
}


using UnityEngine;

public class Player : MonoBehaviour
{
...
    [SerializeField]
    private AudioClip _laserSoundClip, _powerUpSoundClip;
    private AudioSource _audioSource;

    void Start()
    {
        _audioSource = GetComponent();
        if ( _audioSource == null )
        {
            Debug.LogError("AudioSource is missing.");
        }
        else
        {
            _audioSource.clip = _laserSoundClip;
        }
...

    }
...
    void FireLaser()
    {
...
        _audioSource.clip = _laserSoundClip;  // new version added code
        // play the laser audio clip
        _audioSource.Play();
    }

    public void TripleShotActive()
    {
        PlayPowerUpSoundClip();
...
    }

    public void SpeedBoostActive()
    {
        PlayPowerUpSoundClip();
...
    }

    public void ShieldsActive()
    {
        PlayPowerUpSoundClip();
...
    }

    public void PlayPowerUpSoundClip()
    {
        _audioSource.clip = _powerUpSoundClip;
        _audioSource.Play();
// old version removed        _audioSource.clip = _laserSoundClip;
    }
}

Save and test.

Method Two: instantiate an Audio without a gameObject

This plays a clip on some Vector3, from anywhere like a Score text to nowhere like empty space, so no “private AudioSource _audioSourceReference;”

From the online tutoring:

AudioSource.PlayClipAtPoint

Declaration

public static void PlayClipAtPoint(AudioClip clip, Vector3 position, float volume = 1.0F);

Parameters: clipAudio data to play.positionPosition in world space from which sound originates.volumePlayback volume.

Description: Plays an AudioClip at a given position in world space.

This function creates an audio source but automatically disposes of it once the clip has finished playing.

From the Unity—Scripting API


using UnityEngine;

[RequireComponent(typeof(AudioSource))]
public class Example : MonoBehaviour
{
    public AudioClip clip; //make sure you assign an actual clip here in the inspector

    void Start()
    {
        AudioSource.PlayClipAtPoint(clip, new Vector3(5, 1, 2));
    }
}

Here is the code inserted into the PowerUp.cs Script.


using UnityEngine;

public class PowerUp : MonoBehaviour
{
...

    [SerializeField]
    private AudioClip _clip;
...
}

Save and in Unity Editor, highlight a powerup to bring up the Inspector — Power up (Script). Drag and drop Assets — Audio — power_up_sound clip to reference variable.

Drag and drop audio clip to play in the scene

Drag and drop audio clip to play in the scene

There is no reference variable to an AudioSource, but there is a call to the play method “AudioSource.PlayClipAtPoint( _clip, Tansform.postition );”


using UnityEngine;
public class PowerUp : MonoBehaviour
{
...

    [SerializeField]
    private AudioClip _clip;

    private void OnTriggerEnter2D(Collider2D other)
    {
        if(other.tag == "Player")
        {
            // communicate with the player script, through other
            Player player = other.transform.GetComponent();

            AudioSource.PlayClipAtPoint(_clip, transform.position);

            if (player != null)
            {
                switch (_powerupID)
                {
...
                }
            }

            Destroy(this.gameObject);
        }
    }
}

Save and test. The volume of the clip is low. Add Audio Microphone component.