#Update 148 - Audio Source pooling systemI have been meaning to do this post several days so I am happy to finally being able to do it!
I have created an audio pooling system that makes it easy for other components in the game to just ask that system to play any sound at a certain position. It works really well so far and has made it a breeze to add audio.
So this is what the audio source pooling system provides:
- Pooling of audio sources.
- Instantiating new audio sources if there are no available.
- Offers three playback types: One shots, Looping and Background.
One shots are audio that is supposed to only play once at a certain position. For example when the player jumps.
Loops are audio that is meant to be repeated for as long as the calling component wants it to. Usually for as long as the player is close enough to hear it. For example the sound the stompers create when constantly spinning.
Background audio is supposed to always play and does not care about distance to the audio source. Typically used for ambience or music.
How it works in practice One Shots This will be an example for how the players footsteps gets generated.
The player audio script exposes a field of a Sound class called movement. This contains settings for the audio such as which file/files this sound should trigger, the desired volume, pitch and some other settings.
Sound field exposed in the inspector.
The player script then calls the audio manager playing a one shot, like this:
_audioManager.Play (
_settings.MovementLevelSound,
_playerPosition,
_audioManager.SoundType.OneShot
);
The audio manager then grabs an unoccupied audio source from the pool, assigns all the settings from the MovementLevelSound and triggers a coroutine that keeps track of when the sound is done. It then returns the audio source back to the pool and deactivates it.
private IEnumerator HandlePlayingAudioSourceOneShot ( AudioSource audioSource )
{
// Activate audio source and start playing it.
audioSource.gameObject.SetActive ( true );
audioSource.Play ();
while (audioSource.isPlaying)
{
yield return null;
}
// Disable audio source and return it to pool.
audioSource.gameObject.SetActive ( false );
_audioSourcePool.Add ( audioSource );
}
This is what it looks like.
An audio source gets triggered and positioned for each foot step. Also when the player jumps and lands.
In the hierarchy the audio source is parented to the correct root to easier keep track of which audio source is playing what. Also makes it easier to debug.
LoopingFor the looping sounds the calling component is responsible for stopping the audio source. This is because there are different reasons for different component when to stop or start playing looping sounds. So I simply return the audio source to the calling component and then they return it to the audio manager through a call to Stop, like this:
public void Stop ( AudioSource audioSource )
{
// Stop playing the audio source.
audioSource.Stop ();
// Reset.
audioSource.loop = false;
audioSource.gameObject.SetActive ( false );
// Return audio source to pool.
_audioSourcePool.Add ( audioSource );
}
BackgroundThe background audio will loop and play forever. The key here is that all background audio has 0 in spatial blend to avoid being dependent on where the audio listener is in the scene.
Final I really enjoyed creating this pooling system so I hope it was interesting to read about