I’m planning on including a lot of sound clips in my game, and I’m wondering what the best way is to manage them.
For context: I plan on including 20+ ai controlled units fighting each other during battle. They’ll be hitting each other with swords, arrows, spells, etc. So the same audio clip may be playing overtop of itself (ie: two units are swinging their swords around the same time), and I’ll be playing a music track in the background.
The clips are all going to be 2d sounds.
Most guides for playing audio include the audio clips being loaded into audio source components on game objects already in the scene. In my case, I may not know which audio sources are used, because the units that enter the battle can be different. I don’t really want to put audio in the scene and force the scene to load them, if they’re not going to be used. However, loading them via Resources.Load() also feels like it might be too expensive to run “Just in time”.
I think I may use a data structure to pool audio-sources, and try to re-use them as well as hold onto audio clips so that repeated uses of the same sound don’t require runtime loads.
I’d like to be smart about memory management, and keep the runtime performance high for the game in combat. Does anyone have any suggestions?
You could use a single AudioSource and play the sounds with PlayOneShot(clip): many different clips may be played concurrently in the same AudioSource with PlayOneShot, even if some of them overlap in time.
Create an empty game object and add an AudioSource to it, then use this object to play the sounds in all your scripts. Supposing that this object is named “AudioCenter”, the AI script could find and use it like this:
// assign the audio clips in the Inspector
var swordSwing: AudioClip;
var swordClang: AudioClip;
var moanOfPain1: AudioClip;
var moanOfPain2: AudioClip;
...
private var audioCenter: AudioSource; // reference to "AudioCenter"
function Start(){
// get the reference to the "AudioCenter" object:
audioCenter = GameObject.Find("AudioCenter");
}
...
// play sword woosh sound:
audioCenter.PlayOneShot(swordSwing);
...
// play moan of pain:
audioCenter.PlayOneShot(moanOfPain1);
...
I don’t know exactly how sounds are implemented in Unity, but probably PlayOneShot just creates a small temporary control structure each time you call it - the clip itself isn’t replicated, thus you should be able to play lots of sounds at the same time without significant consumption of resources.
You need to write an sound manager to cap your sound effects and pool them at the same time. You can cap them by ID so that sounds played with a certain id are not played if they are over the cap.