I have been implementing some sound effects. Our playable characters, the settlers, contain a bunch of different sound effects and I had to invent a system for handling them. The things I had in mind:
- Allow to later add more sound effects fairly easily in the editor
- Adding several AudioClips for each sound
- A simple way to get a random variation of a sound without dealing with the randomization where the sound is played from
- The AudioSource components should be children of the settler object that plays them, to make use of Unity’s built-in system for 3D space audio
- Not spending too much time on any of this shit, since we have a tight schedule
I made a wrapper class for the AudioSource to include several AudioClips and the ability to set a random one through a function. The main script has a list of instances of this class and this list can be changed in the editor. The whole system is meant to be expanded; as can be seen in the Enum, there is currently only four different sounds. And the NextSound function is not in use yet. I prepared it because I figured you may sometimes want to go through the variations of a sound in order rather than using a random one every time. The code can be seen below:
using UnityEngine; using System.Collections; using System.Collections.Generic; public enum SettlerSounds { SHOT, PICKUP_STONE, PICKUP_WOOD, MELEE_HIT, } [System.Serializable] public class SettlerAudioSource { public SettlerSounds soundIdentifier; private AudioSource audioSource; public List<AudioClip> audioClips; private int currentIndex = 0; public void Initialize(AudioSource _audioSource) { audioSource = _audioSource; audioSource.playOnAwake = false; audioSource.clip = audioClips[0]; audioSource.spatialBlend = 0.8f; } public AudioSource RandomSound() { int random = Random.Range(0, (audioClips.Count - 1)); currentIndex = random; audioSource.clip = audioClips[currentIndex]; return audioSource; } public AudioSource NextSound() { audioSource.clip = audioClips[currentIndex]; currentIndex++; if (currentIndex >= audioClips.Count) currentIndex = 0; return audioSource; } public AudioSource CurrentSound() { return audioSource; } } public class SettlerAudioContainer : MonoBehaviour { public List<SettlerAudioSource> audioSources; void Awake() { for (int i = 0; i < audioSources.Count; i++) { AudioSource audioSource = gameObject.AddComponent<AudioSource>(); audioSources[i].Initialize(audioSource); audioSource.transform.SetParent(transform); } } public AudioSource GetAudioSource(SettlerSounds identifier) { for (int i = 0; i < audioSources.Count; i++) { SettlerAudioSource source = audioSources[i]; if (source.soundIdentifier == identifier) return source.RandomSound(); } return null; } }