Unity Play Examples

How to play audio in Unity (with examples)

In Unity by John20 Comments

I work in Unity a lot and, while I’m always learning, it’s easy to forget that, for a lot of people using the software for the first time, the most useful techniques to know are often the most basic ones.

Once you know the basics it’s much easier to learn more, to experiment and to develop more advanced ideas. So, to help, I’ve decided to put together an easy guide that covers the basics of playing audio and sounds in Unity, along with some real examples that you can use in your project.

So… How do you play audio in Unity?

There are several different methods for playing audio in Unity, including:

  • audioSource.Play to start a single clip from a script.
  • audioSource.PlayOneShot to play overlapping, repeating and non-looping sounds.
  • AudioSource.PlayClipAtPoint to play a clip at a 3D position, without an Audio Source.
  • audioSource.PlayDelayed or audioSource.Playscheduled to play a clip at a time in the future.
  • Or by selecting Play on Awake on an Audio Source to play a clip automatically when an object loads.

Each method has its own unique benefits and use cases and in this article I’ll be explaining how each one works in detail as well as providing some examples that you can use in your game.

What you’ll find on this page

Methods for playing audio and sounds in Unity

Useful examples of audio triggers

How to play audio in Unity

Try my video overview or keep reading for my in-depth written guide, including code examples for you to copy and paste.

How to use Play

//Plays an Audio Source
audioSource.Play();

Call Play from a script to start an Audio Source:

public class PlayAudio : MonoBehaviour
{
    public AudioSource audioSource;

    void Start()
    {
        audioSource.Play();
    }
}

Calling Play will trigger whatever Audio Clip is set on the Audio Source. It’s the most common method of triggering audio and is most suitable for playing looping sounds and music.

This is because some other methods, such as Play One Shot, cannot trigger looping sounds, and also because using Play will only allow one clip to be played at a time from that Audio Source.

Calling Play on an Audio Source that is already playing will stop the Audio Source and start the clip again.

Advertisement

How to use Play One Shot

//Plays a specific clip on an Audio Source once
audioSource.PlayOneShot(AudioClip audioClip, Float volumeScale);

Play One Shot is possibly the lesser known method of triggering a sound on an Audio Source but is extremely useful for triggering sound effects.

public class PlayAudio : MonoBehaviour
{
    public AudioSource audioSource;
    public AudioClip clip;
    public float volume=0.5f;

    void Start()
    {
        audioSource.PlayOneShot(clip, volume);
    }
}

Play One Shot is called on the Audio Source and takes a parameter for the Audio Clip to play. This means that you must specify what clip you would like to play when you call PlayOneShot.

If, however, you just want to play whatever clip is on the Audio Source (like you would with play) then you can just pass a reference to that clip like this:

audioSource.PlayOneShot(audioSource.clip, volume);

You can also set an optional volume scale when calling Play One Shot. This takes a float value between 0 and 1 and will adjust the volume of the clip relative to the volume of the Audio Source.

This is great for variation, because it means that you can pass in a randomised volume value, or play two different clips at different volumes, without changing the overall volume of the Audio Source itself.

Play One Shot is ideal for sound effects, particularly repeating sounds (for example gun fire). Triggering Play One Shot on an Audio Source that’s already playing will overlap the sounds (instead of interrupting it, like it would with Play).

This makes Play One Shot especially suitable for repeating sounds but be careful. Try not to allow too many sounds to overlap all at once.

Despite only playing from one Audio Source, two sounds triggered via Play One Shot will count as two ‘voices’. And even though the maximum voice limit can be increased from the default 32 voices, different platforms have different limitations, so it’s good practice to try to keep the total voice count as low as possible to avoid sounds being culled.

Advertisement

How to use Play Clip At Point

//Plays a clip once at a specific position, without an Audio Source
AudioSource.PlayClipAtPoint(AudioClip clip, Vector3 playPosition, Float volume);

Play Clip at Point works in a similar way to Play One Shot with one big difference. It doesn’t require an Audio Source to work.

This is great for one-off sounds as you won’t need to add an Audio Source component to an object, you can just fire a sound once, from a specified position in the Scene, without any fuss.

public class PlayAudio : MonoBehaviour
{
    public AudioClip clip;
    public float volume=1;

    void Start()
    {
        AudioSource.PlayClipAtPoint(clip, transform.position, volume);
    }
}

Note the capital A in ‘AudioSource’, as Play Clip at Point uses the Audio Source class, instead of an instance of an Audio Source.

You also have to pass in a position that the Audio Clip will play from. In this example I’ve used the position of the object that this script is attached to.

So how does this work exactly?

Play Clip at point Unity

When using Play Clip At Point, Unity creates a temporary Audio Source to play the clip from.

Behind the scenes Unity creates a new, temporary Audio Source to play the clip from and disposes of it once the clip is finished. In the editor you’ll see a new Game Object appear and disappear when this happens. This makes Play Clip at Point especially useful when using an Audio Source Component isn’t an option.

For example, when playing a sound when an object is destroyed.

If the Audio Source is on the object that’s being destroyed the sound will normally be cut off, or it may never get a chance to start, as the Audio Source now longer exists.

Using Play Clip at Point instead allows the sound to continue after the object is destroyed via a temporary Audio Source that is neatly disposed of once the sound is finished.

However, there is a catch…

The downside of using Play Clip at Point

Because the Audio Source that the clip is played from is created at run time, you don’t get the option to change any of the Audio Source’s settings. The Audio Source is created using default settings, with the exception of spatial blend which will be set to fully 3D.

This also means that you can’t use Play Clip at Point with an Audio Mixer. The output will go directly to the Audio Listener, as it does by default.

If you do need to change any of the Audio Source’s settings there are ways you can get around this (by creating your own modified version of the Play Clip at Point functionality). However, in that scenario, it’s probably going to be much, much easier to simply use a regular Audio Source.

Advertisement

How to use Play Delayed and Play Scheduled

Play Delayed and Play Scheduled allow you to play an Audio Source in the future, in two different ways.

Play Delayed

//Plays an Audio Source after a delay
AudioSource.PlayDelayed(float delay);

The first, Play Delayed, takes a delay in seconds and is the simplest method for delaying an Audio Clip.

public class PlayAudio : MonoBehaviour
{
    public AudioSource audioSource;
    public float delay=4;

    void Start()
    {
        // Plays an Audio Clip after 4 seconds
        audioSource.PlayDelayed(delay);
    }
}

This method is easy to use and is ideal for quickly changing the timing of an Audio Source.

Examples of when you would use this include delaying the start of music, sound effects that occur after the event that triggers them, like lightning and thunder for example, and other timing tweaks and randomisations.

Play Delayed is great for simple timing, but it is not suitable for more precise time keeping, like stitching two clips together, or beat matching audio clips.

For that, you need PlayScheduled.

Advertisement

Play Scheduled

//Plays an Audio Source at a precise time
AudioSource.PlayScheduled(double timeToPlay);

Play Scheduled works a little differently to Play Delayed, but it’s incredibly precise.

This is due to the fact that it operates using the actual audio engine time and takes a highly accurate double value, instead of a float.

To use it, you need to specify the time the Audio Source should start, not a delay. This corresponds to the AudioSettings.dspTime, which is the number of seconds the audio engine has been running.

Play Scheduled is ideal for precise audio timing tasks, like queueing audio clips to play exactly after one another, or for beat matching.

The below example hows how to queue a clip to play seamlessly after another clip has finished.

public class PlayAudio : MonoBehaviour
{
    public AudioSource audioSource1;
    public AudioSource audioSource2;

    void Start()
    {
        audioSource1.PlayScheduled(AudioSettings.dspTime);
        double clipLength = audioSource1.clip.samples / audioSource1.clip.frequency;
        audioSource2.PlayScheduled(AudioSettings.dspTime + clipLength);
    }

There’s a lot that you can do with PlayScheduled. So much that I wrote a huge guide on just that, with examples of how to queue up clips, beat match audio and how to end loops with musical stings.

Using isPlaying when scheduling audio won’t work

When scheduling audio using either method, the Audio Source is considered to be playing as soon as it is scheduled and until after it has finished. This happens as soon as the Audio Source is queued, not when the sound starts, so isPlaying will be true, even if no sound is being made yet.

This means that, when scheduling audio, you cannot check if the audio has started or stopped using isPlaying.

How to use Play on Awake

Play on awake is the easiest way to trigger a sound, as it requires no scripting whatsoever.

Play on Awake control in Unity

Play on Awake is enabled by default.

Enabled by default, Play on Awake will start the Audio Source as soon as the object is enabled. This will usually be the start of the scene if the Game Object is already enabled or, if it is disabled, Play on Awake will fire as soon as the Game Object, or the Audio Source, becomes active.

This is useful for automatically starting audio when an object loads, such as music at the start of a scene or a sound that plays when an object is initialised.

For example, to add a sound when a new object is created, simply add an Audio Source component to the prefab of that object and make sure Play on Awake is checked. Then, when the object is added to the Scene, the sound will play.

For more information on the different methods that can be called from an Audio Source, try Unity’s official documentation.

Advertisement

Audio trigger examples

Now you know the different methods for triggering audio in Unity it’s time to put them to work.

Below you’ll find some examples of common audio triggers that you can copy and paste in to your project.

How to play a random sound

What’s the best way to select a random sound in Unity?

First create an Audio Source and an array of Audio Clips.

public AudioSource audioSource;
public AudioClip[] audioClipArray;

Back in Unity, add the different Audio Clips to the Array.

Audio Clip Array in Unity

An Array of Audio Clips

Next, write a function, with an Audio Clip return type, to select one of the clips at random.

AudioClip RandomClip(){
    return audioClipArray[Random.Range(0, audioClipArray.Length)];
}

Then whenever you want to use a random Audio Clip, pass in the function where you would normally pass in the clip name:

void Start() {
    audioSource.PlayOneShot(RandomClip());
}

How to trigger a random sound, with no repeats

To prevent the same sound triggering twice in a row, store the previous sound in a variable and check against it with a while statement, like this:

public class PlayAudio : MonoBehaviour 
{

  public AudioSource audioSource;
  public AudioClip[] audioClipArray;
  AudioClip lastClip;

  void Start() 
  {
    audioSource.PlayOneShot(RandomClip());
  }

  AudioClip RandomClip()
  {
    int attempts = 3;
    AudioClip newClip = audioClipArray[Random.Range(0, audioClipArray.Length)];

    while (newClip == lastClip && attempts > 0) 
    {
      newClip = audioClipArray[Random.Range(0, audioClipArray.Length)];
      attempts--;
    }

    lastClip = newClip;
    return newClip;
  }
}

How to play a repeating sound

Here’s an example of how to trigger a sound repeatedly in Unity, in this case for a machine gun that fires every 0.25 seconds.

I’m also using the Audio Clip array from the last example to use a random sound every time the gun is fired.

public class PlayAudio : MonoBehaviour
{
    public AudioSource audioSource;
    public AudioClip[] audioClipArray;

    public float timeBetweenShots = 0.25f;
    float timer;

    void Update()
    {
        timer += Time.deltaTime;
        if (timer > timeBetweenShots)
        {
            audioSource.PlayOneShot(RandomClip());
            timer = 0;
        }
    }

    AudioClip RandomClip()
    {
        return audioClipArray[Random.Range(0, audioClipArray.Length-1)];
    }
}

How to play a sound when pressing a button

Unity has a built in method for triggering events when a button is pressed and this includes an option for playing an Audio Clip.

Just create an On Click event trigger, drag a Game Object to the object field and select PlayOneShot(AudioClip) from the Audio Source section of the drop down menu.

Play a sound from a button in Unity

Drag an object with an Audio Source to the button On Click event, then select one of the Play options. Easy!

Once you’ve selected Play One Shot, select an Audio Clip to play in the new field that appears.

By using Play One Shot, it’s possible to have different buttons play different sounds using only a single Audio Source.

However, you can also select from Play, or PlayDelayed, just like when playing from a script.

Advertisement

How to start music when entering an area (3D & 2D)

How can you create a music trigger in Unity that fires when the player enters a specific area?

First create the Trigger:

  1. Create a shape, such as a cube that will act as the trigger area in the scene.
  2. Remove the mesh renderer if there is one, you won’t need it for this.
  3. On the Collider component make sure Is Trigger is set to true.
  4. If the Player object doesn’t have one already, you’ll need to add a Rigidbody component for this to work.
  5. Finally, on the Player object, select the Player Tag.
    Player Tag in Unity

Next add this script to the trigger area:

public class PlayOnCollision : MonoBehaviour
{
    public AudioSource audioSource;

    void OnTriggerEnter(Collider other)
    {
        if (other.tag == "Player" && !audioSource.isPlaying)
        {
            audioSource.Play();
        }
    }
}

How to create a trigger sound in 2D

To create the same effect in a 2D project, simply use the 2D Collider and 2D Rigidbody, making sure to update the script to match:

void OnTriggerEnter2D(Collider2D other)
{
    if (other.tag == "Player" && !audioSource.isPlaying)
    {
        audioSource.Play();
    }
}

How to play a sound when colliding with an object (3D & 2D)

Just like entering an area, you can trigger a sound when two objects collide, for example if an object falls on the ground.

Also like entering an area, the object will need to have a Rigidbody component for this to work.

Place this script on the moving object:

public class PlayOnCollision : MonoBehaviour
{
    public AudioSource audioSource;

    void OnCollisionEnter(Collision collision)
    {
        audioSource.Play();
    }
}

To prevent minor collisions triggering the sound, it’s possible to only play the sound for larger collisions, by checking the velocity of the collision:

public class PlayOnCollision : MonoBehaviour
{
    public AudioSource audioSource;

    void OnCollisionEnter(Collision collision)
    {
        if(collision.relativeVelocity.magnitude > 1)
            audioSource.Play();
    }
}

Or, for a more natural sounding collision, you can vary the volume based on the force of the collision.

public class PlayOnCollision : MonoBehaviour
{
    public AudioSource audioSource;
    public float maxForce = 5;

    void OnCollisionEnter(Collision collision)
    {
        float force = collision.relativeVelocity.magnitude;
        float volume = 1;

        if (force <= maxForce)
        {
            volume = force / maxForce;
        }
        audioSource.PlayOneShot(audioSource.clip, volume);
    }
}

The max volume value decides what force of impact will produce the loudest sound. A value that exceeds the max force will simply play at full volume.

Advertisement

How to create a collision sound in 2D

The same method can be used to create a collision sound effect in a 2D game using 2D Colliders, a 2D Rigidbody and updating the script classes to match, like this:

void OnCollisionEnter2D(Collision2D collision)
{
    audioSource.Play();
}

How to play a sound when destroying an object

To play a sound that continues after an object has been destroyed, one option is to use Play Clip at Point, like this:

public class PlayOnDestroy : MonoBehaviour
{
    public AudioClip audioClip;

    void DestroyObject()
    {
        AudioSource.PlayClipAtPoint(audioClip, transform.position);
        Destroy(gameObject);
    }
}

This works by creating a temporary Audio Source that plays at the object’s last position, even though the original object is gone.

Now I’d like to hear from you…

Hopefully these tips and examples will help you play audio in Unity more easily.

At the very least you now know many of the basic options available for playing audio in Unity, making it easier to build more complex audio systems.

But now I want to hear from you…

How will you use these examples in your game? Or maybe your project needs something different, that’s not in this article. What challenges did you face when starting with the basics of audio in Unity?

Let me know by leaving a comment below.

by John Leonard French

Game audio professional and a keen amateur developer.

Get Helpful Game Development Tips, Straight to Your inbox

Get access to exclusive tips & tricks and master game development basics the easy way, with deep-dive tutorials and guides.

Popular Posts

Comments

  1. Hi there, I was wondering if there is a way to trigger an Audio Source to start playing when a Video Player starts? Currently my Video Player is set to Play On Awake AND Wait For First Frame. The problem I am having is that I can’t get the Audio Source to trigger at the same time the video is after it has waited for the first frame

    1. Author

      I’ve not done any work with video so it’s a guess, but I would try checking videoPlayer.isPrepared and start the audio when it’s true. Alternatively I think that there is a videoPlayer.started event that you may be able to use.

  2. Thanks John, I’ll have a play and see what I can do, I was thinking along the same lines but am still quite new to C# so it’s a slow process. I’ll look more into the isPrepared and started states.

    1. Author

      If you’re triggering one-off sounds from a single object you can use PlayOneShot to trigger them. Just pass in a different Audio Clip each time, you can even pass in a different volume.

  3. I’ve assigned a bunch of keyboard keys to gameObjects.. when you press an individual key, i’d like for that gameObject to play a certain audioclip.

    I can’t seem to do this unless I assign an individual script to each key….I don’t doubt there’s a better way. i.e one script assigned to a parent (empty) GameObject, that has all AudioClips assigned to it.

    When you click a button that ‘activates’ a child object, it should play the specified audioclip.

    Thanks,
    Ryan

    1. Author

      There are probably lots of ways you could do this, without knowing your project I couldn’t guess what would be best. That said, because you’re checking for many keys, it probably would be better to use a sound manager style script and some kind of input listener on the parent object. But, unless you’ve got a good reason not to do it the way you’re doing it now (e.g. it’s difficult to manage, or you’re worried about performance) there may not be anything wrong with ‘doing what works’, at least for now. You can email me at [email protected] if you want me to take a look at it more closely.

  4. I want to use Play Clip at Point and also check if the clip finished playing to execute further. Is there a way to do it?

    1. Author

      As far as I’m aware there isn’t a way to cache a reference to the Audio Source that’s created, so it’s not possible to check audioSource.isPlaying. You could, instead, use the Audio Clip duration to guess when the clip will be finished, but that might be a little awkward to use. Depending on what you want to do, it would probably be best to create your own function that works the a similar way (e.g. create an audio source at that position, play it and then dispose of it or reuse it) but this may be more work than it’s worth. Feel free to contact me if you want to discuss it in more detail.

  5. I have a submachine gun with 0.08s fire rate . whether to use Play or PlayOnShot , i can’t make seamless uniform regular auto fire sound effect .

    the auto fire sound seems freaking out or has a stutter in some of points of fire duration.

    I tried Play and PlayOnShot in Update and LateUpdate functions . even i tried cycling 3 audio sources with same audio clip in both functions .

    What do I do ?

    1. Author

      First off, probably use play one shot. Secondly, how are you measuring the interval? For example, if you’re using a float timer, subtracting the interval duration after firing can be more accurate than resetting it to zero.

  6. There is this problem in most shooter assets like UFPS 1.7.5

    this is a simple fire Sound functions that common in most assets .

    nextFire=0;
    fireRate=0.08;

    void FireSound()
    {

    if (Input.GetButton(“Fire1”) && Time.time > nextFire)
    {

    nextFire = Time.time + fireRate;

    AudioSource.PlayOnShot(SingleShot_fireClip);

    }
    }

    pleas create an empty game object and attach a script to it and try above function in Update loop Function .

    1. Author

      In my experience, you can’t get perfect audio timing when triggering Audio Sources from Update. Your options are to make a loop of the sound you want and play that back or, if you want to trigger it perfectly, use PlayScheduled. Below is an example of how to play a repeating sound in accurate time using PlayScheduled. You’ll need two Audio Sources for this. In this example I used a bool trigger to test with, just swap that out for your fire button.

      using UnityEngine;
      
      public class MachineGunFire : MonoBehaviour
      {
          public bool firing;
          bool firstShot = true;
      
          public AudioSource[] audioSources;
          public int toggle;
          public AudioClip audioClip;
      
          double nextTime;
          float lookAhead = 0.04f;
          float fireRate =0.08f;
      
          private void Update()
          {
              if(firing)
              {
                  FireShots();
              }
              else 
              {
                  // This gives the timer a starting point and tries to play the first shot as quickly as possible
                  firstShot = true;
              }
          }
      
          void FireShots ()
          {
              if (firstShot)
              {
                  nextTime = AudioSettings.dspTime;
                  firstShot = false;
              }
      
              if(AudioSettings.dspTime > (nextTime - lookAhead))
              {
                  FireShot(nextTime);
                  nextTime += fireRate;
              }
          }
      
          void FireShot(double timeOfShot)
          {
              // remove this line if you're only using one sound. So just manually assign in the inspector
              audioSources[toggle].clip = audioClip;
      
              audioSources[toggle].PlayScheduled(timeOfShot);
              toggle = 1 - toggle;
      
          }
      }
      

      I quickly wrote and tested this, so it’s not a perfect example, and there are other ways to do what you want. However, if you want precise playback timing, this is one way to get it.

      Hope that helps.

  7. Very nice . thanks
    It is work good but AudioSettings.dspTime has conflicts with Time.time .

    Otherwise must to modify entries code .

    1. Author

      That’s right yes. Time.time, and AudioSettings.dspTime are different, and can’t be used interchangeably. However, so long as Audio time keeping is done in dspTime, it can be used with Time.time based functions (as I’ve done in the example when looking ahead to check if a new clip needs to be scheduled). But, if you want it to be rock solid, this is the way to do it, or make a ready-made firing loop.

  8. I dont know if this is out of date but I had to refactor my code for 2d collisions to this:

    using System.Collections;
    using System.Collections.Generic;
    using UnityEngine;

    public class Block : MonoBehaviour
    {
    public AudioClip audioClip;

    void OnCollisionEnter2D(Collision2D collision)
    {
    AudioSource.PlayClipAtPoint(audioClip, transform.position);
    Destroy(gameObject);
    }
    }

  9. Hello John,
    Thank you for the wealth of information that you have provided for us. They are very practical and very useful. I really appreciate it.

    As I was reading through your article I noticed something about the use of the Random.Range function in your codes.

    The arguments for the Random.Range() , are both inclusive(when they are floats) but when they are integers like this in one of your lines:

    “Random.Range(0, audioClipsArray.Length – 1)”

    The maximum one is exclusive and so we must not subtract 1 from it.

    Thank you.

    1. Author

      Thanks for the tip! I didn’t realise this (as I always seemed to get out of range exceptions somehow anyway!). I’ve updated the article and will remember this in the future.

  10. hello john
    first of all i want to thanks for your useful and professional articles and then explain my problem.
    problem is whenever two audio clips with playoneshot method is playing at the same time one of them getting fade(decreases sound).
    these two clips are playing from two differenct gameobjects with two different audiosource!
    player and enemy shooting each other at the same time.
    do you have any idea how can i solve the problem?
    thanks a million.

    1. Author

      Sounds like there’s something else going on here, what it is depends on how the sound is getting lowered (i.e. is it being culled, an audio mixer effect etc.) I see you’ve emailed me also so I’ll reply to that and if you can give me more details that would be helpful.

Leave a Comment