Play On Awake

How to play audio in Unity (with examples)

In Audio by John FrenchUpdated 52 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

Related Articles:

How to play audio in Unity

Here’s a quick overview of the five different methods and how they work.

 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.

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 gunfire). 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.

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.

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 timekeeping, like stitching two clips together or beat matching audio clips.

For that, you need PlayScheduled.

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.

Ready-made options

While Unity’s built-in options for handling audio are much better than they used to be, if you want easy access to advanced audio features (or even if you just want to save some time) you might want to consider an audio manager plugin from the Unity Asset Store.

Master Audio, for example, has long been the gold standard in audio manager assets. Fully featured and well supported, it offers advanced features, such as audio occlusion, as well as basic conveniences, such as solutions for adding sounds to odd-shaped objects (such as rivers for example). The Multiplayer version extends the asset further, making, normally challenging, multiplayer audio, much easier.

For larger developers, Fmod and Wwise are powerful audio integration options, both of which are compatible with Unity (Fmod has a Unity plugin which you can download from the Asset Store here). While powerful, their advanced features are offered under licensing tiers which are, much like Unity, based on revenue and production budget. For more, check the official websites here: Fmod, Wwise.

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.

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.

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.

John French profile picture

by John French

Game audio professional and a keen amateur developer.

Get Game Development Tips, Straight to Your inbox

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

How this content was created

This article was written using first-hand research and experience, without the use of AI. For more information on how Game Dev Beginner articles are written, see my writing policy.

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.

      1. Hello there!
        I have an issueā€¦

        I have a .wav file i want to use in my pong game to play when the ball collides with either of the paddles.
        I created the public variable for the audioSource, but I canā€™t get the audio file linked to that variable. Any idea why that is?

        1. Author

          Hi there, so just to run through the basics. Drop your WAV file into Unity, which imports it as an Audio Clip. Add an Audio Source component on to an object in the Scene, which is where the sound will come from. The Audio Source component has a field for the Audio Clip, which is here you add your sound. Then, in scripting, get a reference to the Audio Source, then you can play it using audioSource.Play(); etc.

          Apologies if you know all that already.

  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.

    2. I know it’s too late for respond but It might help to another.
      With this kind of situations, I’m using animation events. With animation events, you can set method to work for spesific frame. You can PlayOneShot firing sound desired frame.

  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.

      1. I know It’s been 2 years but, did you find any solution for this? I am facing with this problem right now, and couldn’t find any solution. It seems this kind of problem rarely happening.

        1. Author

          Looking back, Omid’s particular issue was to do with outputting to the wrong mixer by mistake. There’s not a common cause or error that I know of for this so it’s usually caused by something specific to your project, in which case email me at [email protected] with more information (if you can show me it happening, that would be useful) and I can try to help however I can.

  11. Hi John, this article has been super useful thank you!

    Wondering if you could assist with something? I have the following script:
    ———————————————————-
    public class OnTriggerPlayOneShot: MonoBehaviour

    {

    public AudioSource TriggerSound;

    public void Awake()
    {

    TriggerSound = GetComponent();
    }

    public void OnTriggerEnter(Collider other)

    {

    TriggerSound.Play();
    Destroy(gameObject, 2f);
    }
    }
    ———————————————————-
    As you can see, once the sound is triggered it will destroy the associated object after 2 seconds. What I would like to do is check if AudioSource.isPlaying = false to destroy the object so that the script can be used on sounds of varying length.

    I know what I need to do I just can’t work out the syntax!

    Any assistance would be most appreciated

    Regards

    1. Author

      You could do this in a few ways. One simple method to split logic over a number of frames is to use a Coroutine. With that you could wait for the sound to stop playing before doing anything else. Something like: while(TriggerSound.isPlaying){yield return null;} then place the Destroy line after.

      Another method is to simply pass the length of the clip into the Destroy method, e.g. Destroy(gameObject, TriggerSound.clip.length);

      Hope that helps!

  12. Hi John
    Thank for you
    I have some weapons single shot sound effect .
    How can generate or make a nice auto fire loop from a single shot with Audacity or other tools ?
    I tried these solutions.

    I cut the sound from the first as much as the firing rate time and then made a loop with it.
    It didn’t go well, it became very monotonous without details.

    I cut a longer length of sound, for example 0.3 seconds, and after creating loop, I used the CHANG OF TEMPO effect in Audacity to increase its speed. But the problem was that the single and looped sounds were a little different, as if the looped sound came from another gun.

    What is your suggestion ?

    1. Author

      Some tips that might help:

    2. * Checkerboard the sounds (put them on two tracks, and alternate) if they overlap, so that they don’t cut each other off.
    3. * Keep the timing fairly precise between each shot
    4. * If you have multiple samples, layer them together with a “base sound” that’s common to every shot, this will help them sound the same but different
    5. * Change the volume and pitch of each sample slightly, as you’ve already tried but be very subtle.
    6. * Only make small changes, the trick is to not be able to hear the difference between the samples. An obvious difference be will noticeable in the loop
    7. Hope that helps!

  13. Hi John,
    How would I play two looping background music tracks simultaneously out of the same object? (such as a melodic music track and a footsteps/beats track playing simultaneously out of the same object)?

    – Since “audioSource.Play()” plays a single looping music track…
    – In my code I have “audioSource” and “audioSource2”.
    – I also have “audioSource=GetComponent()” and “audioSource2=GetComponent()” which seems to assign both audio sources to the same object (though I’m not quite sure what object exactly it’s grabbing, looks like it’s grabbing the gameManager).
    – Each audio source is set to playing a different Clip (one melodic and one beats).
    – But when audioSource and audioSource2 are both made to Play, the first one seems to be immediately overridden by the second, and only the second one is heard.

    What would be a more proper way to implement this?
    Thanks,
    – Adam (fairly new to Unity and C#)

  14. Thanks for the reply, John.
    It sounds like my “audioSource=GetComponent()” and my “audioSource2=GetComponent()” are both assigning audiosource 1 and 2 to the same exact gameManager object (which does have an AudioSource component in it, and that is what is being grabbed by both of them).

    So then when either source 1 or 2 is made to Play, it’s the same object component (gameManager in this case) that is doing the playing, and it will only respond to the most recent command from either source 1 or 2 (but not both simultaneously since audioSource.Play() on any singular particular object only plays one track at a time).

    As you suggested, I next manually assigned each audioSource (1 and 2) to a different object component (each one having its own AudioSource type), and that worked. It allowed both tracks to be played simultaneously (since each was effectively playing from a separate object). Thank you!

    I guess my original question should have been, is it possible to use the “audioSource.PlayOneShot()” function with a “looping” option? This would allow the same instance of an AudioSource component to play two different audio tracks simultaneously in an overlapping fashion (so I wouldn’t need to parent the different tracks to different objects/components). But given it is called a “one shot”, I’m guessing it is not capable of looping, and only plays each overlapping track once.
    Maybe if there’s a way to detect if each “one shot” simultaneous track has stopped playing, so I can then manually restart it…
    Am I understanding this right?

    Thanks for the reply, appreciate it.
    – Adam

    1. Author

      That’s right. Play One Shot can’t loop but can play multiple sounds via one Audio Source component. Best bet to make a looping oneshot sound would be to use a timer to trigger the rate at which you want the sound to trigger. You can use AudioSource.isPlaying to check when a sound has finished however in that case there’s no need to use play one shot. If you want to queue sounds, use PlayScheduled instead, that way you don’t have to check constantly to see if it’s finished ().

  15. Yeah, looks like the GetComponent() assignment executed for both audioSource and audioSource2 was assigning them both to the same exact object instance, and so when both were Played the object would respond only to the most recent one, since audioSource.Play() only plays one audio Clip at a time.

    As you suggest, I manually assigned audioSource 1 and 2 to two different objects/components and now they can play simultaneously (since now each one is playing from a different object instance).
    I suppose I don’t even need two different Objects, just two different Components of the same AudioSource type on the same Object would be enough to individually/uniquely link audioSource 1 and 2 onto?

    I guess my original question should have been, is there a way to use audioSource.PlayOneShot() with a “looping” function?
    This way the same Object and Component instance can play two different overlapping Clips simultaneously (I do not need to parent the audioSources to two different objects or components), but can it play them each in a “loop”?
    I imagine no looping is available since the name is PlayOneShot (no looping implied).
    Maybe if there’s a way to detect when each of the Clips in the PlayOneShot has finished playing, so it can be manually restarted again…
    Am I understanding this right?

    Thanks again for the quick response,
    – Adam

  16. Hello Friend! I want to thank you for your willingness to teach all these Audio tips. I have a question and I hope you can help me: I have two objects that emit the same audio source. In scene, when the two objects emit sound, the sound is multiplied. So if I put 30 objects on stage, I’ll have to turn the volume down, otherwise the speaker will blow up!! How to make two or more objects emit their respective sounds independently? In other words, can I have 100 objects replicating the same audio source without them doubling the volume? Thanks!!!

    1. Author

      How you handle this depends a lot on the type of sound you have. For example if you have a looping sound, you could change the start time of the clip to something random (AudioSource.time, if I remember right) and that would help avoid some of the doubling. However… you’re always going to run into issues when multiplying the exact same sound, because it’s adding the same frequencies on to the same frequencies. The only real way to deal with it is to change how each clip sounds, so the timing i.e. the playback position, the pitch, 3d position in the world or, best case, to vary the actual sounds that are played, if any of that’s an option.

  17. Sir,
    let me ask, how to add sound on scrollview ,horizontal scrollbar, when swipe object

  18. Hi John,

    I’d be interested to hear your take on rhythm based games like Crypt of the Necrodancer. How would you go about clamping animation frames to a specific beat that is always in sync with the music?

    1. Author

      My understanding is that animation is scaled by delta time to keep the speed consistent across variable frames, so it should be fairly straightforward to run an animation for a specific amount of time. However, in my experience, beat-matched systems tend to fall out of time if they’re managed using floats, so as long as the system runs off of the AudioSettings.DSPtime as a kind of master clock, to start animations on a beat and to trigger events, it should be possible to keep everything in sync.

  19. Hi. I’m trying to make an oncollision2d sound when the player hits a wall but i only want it to play once per life. Meaning if the player hits the wall and dies I don’t want it to play again when he lands on the floor. How do I do that?

    1. Author

      One simple method would simply be to check if it’s been played before. i.e. declare a bool called hasPlayed, check that it’s false before playing the sound and set it to true when the sound is triggered.

  20. Hey John! thanks for the tutorial. I was wondering how i can randomize the start position of my background music thats play on awake… Any idea?

    1. Author

      You can randomise the position with AudioSource.Time and Random.Range (using the length of the clip as an upper max). If you do that in Awake, off the top of my head it should work, but there’s a chance it would start to play first and then change position. For that reason, you might be better off not using play on awake and, instead, start the audio source from the same script you randomise it from, immediately afterwards.

  21. Hi John,

    Thanks for this it’s very helpful. But I just have one question.

    I’ve used your script for triggering audio when entering an area, for me it’s a looping piece of music and it’s worked. But when I leave an area the music keeps playing. Is it possible to have the music stop playing when I leave the area?

      1. So just a different trigger area with the same script except with audioSource.Stop() instead of audioSource.Play()? Sorry I’m a total noob and I tried that but it didn’t work

  22. Hey John. I am a sound designer and just starting to learn Unity. The task is as follows: In a project, I am destroying an object using a RayFire script and I need to get sound from falling fragments when they collide with the ground and with the fragments themselves and other objects. Ideally, from large and other fragments, I should be able to trigger events with the right sounds.
    I use Wwise, but if you explain to me the principle of work in this case in Unity, then for sure I use this principle in Wwise.
    I thought to solve it with colliders on which the fragments fall, but in this case it is impossible to track their size and voice the collision of the fragments with each other. Ideally, I should solve all this in Wwise with the launch of events with different random containers.
    Please tell me how would you solve this.
    Thanks!

    1. Author

      Hi Yury. Yeah, I’d do it in Wwise as you suggested. While you could probably do something with Rigidbody physics values and on trigger events, triggering multiple sounds like that, even using one audio source (with one-shots) would add a handful of voices to the total count. While Unity audio is pretty good, there’s probably a more efficient way to do this with Wwise.

  23. Thank you so much. but…
    I’m using the animator with an NPC and the animations are ready. I’m using vuforia with more than one target. But even when the target is not active the sound of the NPC is playing, how to make the audio play only when the target is activated and animation appears? I tried using ImageTarget events to make the sound play only when the target is active, but the sound plays from the beginning as if the animation is active.

    1. Author

      There are a lot of things this could be, but assuming you’ve ruled out some of the simpler causes (like leaving Play on Awake checked, for example) then, if the animation works correctly, you could try triggering the sound from the animation instead. That way, it should only play when the animation does. However there are lots of reasons this could be happening so, if you’re still struggling with it, email me at [email protected] with more details and I can take a look.

Leave a Comment