How To Play Sound Effects In Unity
All this game development work, now I get to do something I already know and love… Sound!
Let’s start simple and add some background music. By default, our camera already has an Audio Listener attached, and since our game is a 2D static screen, this is the perfect spot for our audio to be heard. The common alternative is to have our Player carry the Audio Listener, as this allows full immersion of where our character is in the world.
First, we can create an empty game object and call it AudioManager, we can potentially use this to create dynamic changes or to control volumes. But for now, we will simply use it as a parent for our Background Music game object. On this new child object we simply want to add an Audio Source. On this, we can drag in our desired music as an AudioClip, check Play On Awake and Loop. Now we should have a looping background music layer.
Now let’s look at playing sound through code. To add a laser sound, we can add an Audio Source to our Player. We do this as opposed to on the Laser prefab as the Player is what already has our Instantiate function we can append sound to. We may also want to have our Player be responsible for multiple sound effects so let’s not add a clip as we did for our background music. Be sure to uncheck Play On Awake and Loop to prevent any unwanted sounds occuring.
Instead we need to create a AudioClip variable and add our laser sound in the inspector. To play the AudioClip, we need to access our AudioSource, this can be done like all other GetComponent functions we have used previously. Once again, remember to null check!
Now in our Fire Laser method, we can use .PlayOneShot(). Alternatively, we could simply use .Play() but later, when we add our explosion sound, the AudioSource would cancel clips out if we were to call them at the same time.
We can do a similar thing for our Explosion sound, but we simply call .Play() in our Start method, as the Explosion script is Instantiated whenever another script calls it. Our explosion already waits for the animation to finish before destroying itself, so our sound effect should be fine, but it is worth checking the lengths against each other.
Our enemy explosion works a bit differently. We don’t Instantiate our explosion prefab, instead, we change animation states, to save our OnTriggerEnter2D method getting too long, we can create a new EnemyDeath method that can be called in our collision checks.
While the normal explosion animation last’s longer than the audio clip. The enemy explosion animation does not. We can instead delay the Destroy function by a variable storing the length of the audio clip. It would be better if we create a function to compare the lengths and store the longer of the two, incase we decide to change animations or sound effects. But personally, I’m going to be rewriting all this audio code with Wwise to create better immersion.
Now let’s add a sound for when we pickup powerups. Our powerups are destroyed immediately as there are no animations triggered. We could disable both the Sprite Renderer and the Collider, or, we could use .PlayClipAtPoint(). This allows us to create a separate Audio Source that destroys itself AFTER the audio clip has played. This is great in the 3D realm, as we can simply have it play at the transform.position. But, we’re in 2D and therefore want it to play in the same position as our Audio Listener otherwise we’re going to run into immersion problems. To do so, we can create a Vector3 variable to store the position of the Audio Listener and then use GameObject.Find to locate our Camera and it’s transform position.
With that, we have some basic sound effects being triggered in Unity. This is probably all we need for our simple 2D game, but tomorrow, I’ll be posting an article on using Wwise to create a more immersive soundscape with the same four audio clips.