Playing Sound Effects in Unity
Play()
There are quite a few ways we might go about doing this in Unity, perhaps the simplest of which (and the one which tends to get taught first), is placing an AudioSource component on an object, create a public reference to it, assigning an AudioClip to it, and calling Play:
Doing so will set the clip for the AudioSource until its changed, which can be good if you know you’ll be looking to play the same sound over and over again.
PlayOneShot()
An alternative, which’ll only temporarily change the clip in order for it to play, is to use the PlayOneShot method:
Not only does this let us tell and AudioSource which clip to play and get it to play within the same statement, the method also gives us the option to set the volume at which it plays (as we’re doing with the second sound). And beyond this, another handy tidbit is that we’re able to play multiple sounds at the same time through the same AudioSource using this method, meaning that second PlayOneShot call doesn’t actually stop/interrupt the first in order to start playing.
PlayClipAtPoint()
I don’t think I’ve ever actually used this one myself, but it certainly sounds useful. Rather than need to play a clip from a pre-existing and specified AudioSource, this method will actually create, set, and play an AudioClip from an AudioSource at given point in world space:
The method requires an AudioClip and a Vector3 as arguments, but will also accept a float to determine the volume the clip is played at (as with PlayOneShot). This Vector3 can be any point in world space, and in the above example I’m setting it to spawn and play at the same position this script is attached to. The created AudioSource will automatically destroy itself once the clip has finished playing, and since it exists fairly independently of any script or other object it’s a great option for when you need to, say, destroy the object which calls the sound without interrupting the sound itself (for instance, with explosions, collectibles, enemy deaths, etc.).
AudioManager (custom class)
An alternative, and one which a Brackeys video introduced me to, is to have an AudioManager object which will handle and play the majority of the sounds you need in a level. This way, we don’t need to create dedicated AudioSources each time we want to play a sound — they’re created in advance and separate from any object which uses them. He’s does this by creating an array of a custom class (‘Sound’), which is then used within the Awake method to create and prepare a dedicate AudioSource to play that sound (which can then be called by a string ‘name’ variable):
I believe he then recommended making slightly longwinded function calls like FindObjectOfType<AudioManager>().Play(“MySoundName”) in order to play the sound from any object in the scene. It’s incredibly convenient but not especially performant, particularly with its use of the FindObjectOfType function (which, to quote Unity’s own documentation, is ‘very slow’). I’d recommend making this function call once within the start method of an object and then just storing a reference to it for whenever you need it, particularly if you know you’re going to need to play multiple sounds. Better yet, just create a public reference and drag the AudioManager instance into it within the inspector (if you’re able to do it pre-runtime, that is).
I’m not personally sure how performant Array.Find is, although I imagine it’s as performant if not more performant than iterating through each of the elements in a loop, but inevitably it’d be less expensive to know exactly which AudioSource to use/play the clip through without looking for a specific one. It might be better to use PlayClipAtPoint, but to be honest in a lot of smaller projects we probably won’t need to worry all that much about the performance of what’s probably a fairly short array to look/iterate through.
Conclusion
There are no doubt other nifty ways of playing audio in Unity, but I hope this covers some of the main ones you can use in your projects!