How to Play Sound Effects in Unity
Objective: let’s add some sound effects to various game events in our 2D game project.
In the first part of this article (https://myjl-besnard.medium.com/immersion-starts-with-sound-6e59e9f1a6c7) we added some background music to our game project. Now let’s continue our journey into the Game Audio section of our 2D Space Shooter game project from GameDevHQ by adding sounds effects triggered by events in our game. We will now add audio clips to give our laser shot, explosions, and powerup collection some life!
Laser Shot Audio Clip
Next, we will tackle adding specific sounds effects to the various game events, beginning with the Player’s laser shot. Set up a couple of private variables in the Player script. The first one is of type AudioClip which will store a reference to the sound effect that will be played. The second one of type AudioSource which hold the reference to the Audio Source component on the Player that is told to play the stored sound effect in AudioClip.
In the Start() method, you then get the Audio Source component from the Player and assign it to _audioSource, run a null check, and if it is not null set the clip to _playerLaserShotAudioClip via code.
In order to play the sound, add _audioSource.Play() to the PlayerFireLaser() method. This will play the sound stored in the _playerLaserShotAudioClip through the Audio Source every time the Player fires his lasers.
Select the Player in the Hierarchy, and drag the “laser_shot” audio clip into “Player Laser Shot Audio Clip” script field (_playerLaserShotAudioClip private variable).
Again, with the Player selected, add a Audio Source component. It doesn’t matter if you drag the “laser_shot” into the AudioClip field, since via code, if the _audioSource is null, the _audioSource.clip will get set to the value of the _playerLaserShotAudioClip variable (which is “laser_shot”). Make sure you have deselected Play On Awake since the laser shot sound should be triggered only when the Player fires.
Now doing all this will work great but there’s a slight script modification we can do to our Player’s Audio Source to make it more flexible by creating a method in the Player script which will play whatever audio clip we assign to it. For this, we will use the PlayOneShot(clip) function. This will allow us to play audio clips independently, and they won’t get cancelled out by other audio clips such as explosions or laser shots.
Let’s start by removing the else statement in the Start() method which sets the “_audioSource” to “_playerLaserShotAudioClip”.
Then let’s create a new public method in the Player script called PlayClip() which will look for an “AudioClip” that is stored in “soundEffectClip”.
Finally, change the _audioSource.Play() and replace it with PlayClip(_playerLaserShotAudioClip) in the PlayerFireLaser() method.
And with this, we now have a laser sound effect for our valiant Player. Let’s move on to explosions…
Explosion Audio Clip
We have a few occasions where the explosion audio clip needs to be triggered: when the Asteroid blows up, and upon collision detection between the Enemy game object and the Player laser or Player spaceship.
The Asteroid gets replaced by the Explosion prefab, so it makes sense to simply add an Audio Source component to the Explosion prefab with the stored “explosion_sound” audio clip set to Play On Awake when the prefab is instantiated.
When dealing with the other scenarios (Enemy dies, Player dies), both get detected in the Enemy script via the OnTriggerEnter2D method, so it makes sense to use this as the location to setup playback of the “explosion_sound” audio clip.
Start by adding a Audio Source to the Enemy prefab (or as in my case I’ve selected both the Enemy and EnemyDodging prefabs since I have multiple adversaries), and drag in the “explosion_sound” audio clip. Set Play On Awake to false.
Once this is done, we need to do as we did in the Player script with the Laser audio clip, and set a reference to the explosion audio clip in the Enemy prefabs. Create a private AudioClip “_explosionSoundeffect”, as well as a reference to the Audio Source component with another private AudioSource variable “_audioSource”.
In the Start() method, get a reference to the AudioSource component and store it in “_audioSource”, followed by a null check. If the “_audioSource” is null, set it to the “_explosionSoundEffect” value to avoid any errors.
Add _audioSource.Play() to your OnTriggerenter2D method, just before we destroy the Enemy game object, when collisions are detected with both the Player’s Laser and the Player itself.
Compile your changes. Then, select your enemy prefabs, and drag the “explosion_sound” into the Enemy and DodgingEnemy scripts “Explosion Sound Effect” field.
This completes the steps required to add the “explosion_sound” audio clip which gets triggered upon Enemy game object collision detection with the Player Laser or Player game object. Let’s wrap it up with the Powerup collection sound effect.
Powerup Sound Effect Audio Clip
The Powerup sound effect offers a different sort of challenge. Whereas before, the other game object were destroyed following a certain time delay which allowed the associated sound effects to be heard. With the Powerup, they get destroyed upon contact with the player game object, so we would never be able to hear any sound effects.
The problem can get resolved in two ways: either create a stand alone game object which gets instantiated at the Powerup transform position, and use this new game object to hold a reference to, and play, the Powerup “power_up_sound” sound effect. These same game objects would self-destruct after the clip has finished to avoid cluttering up the Hierarchy.
You then need to drag in the “power_up_sound” audio clip into each PowerUps prefab.
You then need to use the PlayClipAtPoint function found in the AudioSource class. Unity describes this function as “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.”
In the PowerUps script, add the following line before destroying the Powerup:
AudioSource.PlayClipAtPoint( _powerUpAudioClip, transform.position)
This will create a temporary Audio Source game object at the transform position of the collected Powerup, play the audio clip, then destroy itself once the audio clip has finished playing.
The second option is to simply use the PlayClip() method that we built in the Player script. This is much more simple since we are already getting a reference to the Player script in the OnTriggerEnter2D() method of the PowerUps script.
To do this, add a private AudioClip “_powerupAudioClip” to hold a reference to the “power_up_sound” audio clip in the Player script.
Then, in the PowerUps script, remove the PlayClipAtPoint function and replace it with the following line inside the player null check:
player.PlayClip(_powerupAudioClip)
This allows you to use the PlayOneShot function of the PlayClip() method, playing the “_powerupAudioClip” reference held in the “soundEffectClip”.
This conclude my article on how I implemented various sound effects into my game project. As always, there are multiple solutions available, and it’s important to take the time to understand the solutions you opted to work with. And finally, experiment, have fun and always strive to find various ways to optimize your code. Thanks for reading! :)