We are proud to announce that our proven Unity Audio Toolkit (already in use by numerous commercial projects) has now been launched on the Asset Store. The current version v2.2 offers all the features a professional application requires to manage and play music and sound files in an easy and performance optimized way:
ease of use: play audio files with a simple static function call, creation of required AudioSource objects is handled automatically- conveniently define audio assets in categories using the customized inspector view- set properties such as the volume for the entire category- change the volume of all playing audio objects within a category at any time- define alternative audio clips that get played with a specified probability or order- uses audio object pools for optimized performance- set audio playing parameters conveniently, such as:
o random pitch volume
o minimum time difference between play calls
o delay
o looping
o fade out / in
special functions for music including cross-fading
delegate event call if audio was completely played
playlist management with shuffle, loop, etc.
BONUS: If you buy the Audio Toolkit you get our generic and extremely simple to use object pooling class for free! It can be used on any type of game object such as visual effects, etc.
Yes - you get the complete C# source code in the full version. The free version only contains a mono DLL.
If you are missing a specific feature - please let me know and we will probably be able to update the toolkit quickly.
Hey there. I had some quick questions. So this creates a new game object w/audio source for every sound that gets played? (If so, I can see where the object pooling came in handy here.) How would you use this API to play, say, a random sequence of sounds such as footsteps? does it try to continually create new game objects or can you reuse the same one for each foot?
Yes, a new AudioObject with an AudioSource component is created every time a sound is played. And the AudioObjects are pooled by default to enable the best performance possible. So you don’t have to do anything special for your footsteps sounds. Just create an “audio item” and name it e.g. “footsteps”. Next, assign as many footstep sound variations as you wish to this audio item (the audio clips + settings, we call them “subitems” ). Then the different footsteps sound can either be played randomly or as a sequence in a fixed order. In the script you just call AudioController.Play( “footstep” ) and the toolkit will handle everything for you.
No. The audio toolkit can not know at what points of time each footstep sound has to be triggered. You have to call AudioController.Play( “footstep” ) yourself each time the foot touches the ground during your particuliar run animation.
But, using the audio toolkit, the sound artist can easily set as many variations of the footstep sound as desired (without script code changes) and the toolkit will choose the audio clip according to the settings (either randomly or in fixed order).
Please have a look at our demo scene that also comes with the free version and I am sure you will quickly understand the concept.
Cool. I downloaded your free version to check it out. It’s very well thought out. Great job.
I was able to centralize all my sound files and it makes it really easy to manipulate them.
I’ll be picking this up soon.
One other quick question, is there a way to crossfade between sound file collections in an audio item?
Would all the files need to be in separate playlists that use ‘crossfade’?
thanks.
Not sure what you mean by “crossfade between sound file collections in an audio item”.
Automatic cross-fading is only done when you call AudioController.PlayMusic() or you play a playlist ( with AudioController.PlayMusicPlaylist() ).
However, you can always cross-fade manually by calling AudioObject.Stop( fadeOutTime ) and AudioObject.FadeIn( fadeInTime ).
Hope that answers your question.
General appeal to all Audio Toolkit users: If there is a specific feature you are missing about the toolkit - please let me know and we will see to implement it during our next software update iteration.
As an example, if you had a collection of, say, one second long wind sounds and wanted them looping, ideally you would have a way to crossfade between the sound files so you don’t have one wind sound end, then another start, etc. Another use would be for ocean waves breaking…or footsteps sloshing through water. If there isn’t a quick way to do this in AudioToolkit, I can write a coroutine that fades out and brings in sounds in an audio item group.
I think that is something rather specific. Plus you would probably also want control over which specific sound effect is played and at what time (e.g. every now and then a storm comes up and you should play a couple of stormy wind sounds in a row). I think you go best if you implement your custom solution for this. Using the toolkit’s fade in/out functions this should be quite easy.
Actually I’m using this quite a bit in the game so far. It can be a good space saver to have multiple small sound files that get randomly played and looped rather than one large one that keeps repeating itself …or having multiple sounds randomly play back one after another without crossfading which starts to sound unnatural. By shuffling their order and crossfading, even at random times, it can simulate a much more natural, less detectable, repeating sound field. As I said, not just for wind, but for ocean, water splashes, wood creaking on a ship, any sounds that get repeated and loop. Using Audio toolkit’s fading functions in my coroutine is now getting me the right effect.
thanks,
-p
Sure - just import the paid version package and then delete the AudioToolkit_FreeVersion.dll. All your settings will remain.
If you want to use pooling don’t forget to add the PoolableObject script to your AudioObject and enable pooling in your AudioController.
I have a case where I would like the pool count to be the limit on the number of sounds that play. For instance, imagine I have a tower defense or RTS game with lots of little units. All of the units fire projectiles and there are 100 explosions that all happen within a few frames of each other. But, I never want to play more than say 10 explosion sounds at once. More than that… and the additive volume is too high and it generally sounds bad.
So, I set the pool size to 10. Looking at the source, it looks like this means that the 11th simultaneously played sound will call InstantiateWithoutPool(). This of course creates an new object.
Is there a way to limit the simultaneous sounds that play? I suppose I could keep a count myself, but I would have to decrease that count whenever each sound finished playing. Can this be done (delegate?) reliably?
I may be missing something obvious (just purchased a few hours ago and have only started looking into it in the last 20 minutes).
You can’t limit the number of AudioObjects with the pooling feature. Actually this is not what you will want in the end. If you limit the number of sound objects then you could have e.g. have a situation where 20 explosion sounds are triggered at once plus you want a voice saying e.g. “Attack!”. Then you will want the attack voice to be played in any case.
You can solve this problem by using the “Min Time Between Play” value of the audio item which is already set to 0.1 be default. This value will prevent the same audio item to be played within the time frame of 0.1 seconds.
Let me rephrase the question/feature request to ignore pooling:
I need to me able to limit any sound effect so that only N of a given sound effect are playing at the same time. I don’t need a global limit, it needs to be per sound. For instance, I never want more than 5 explosions playing at once, more than 10 lasers firing, more than 3 air raid sirens, etc. For some sound effects, I don’t want a limit (like the Attack! voice in your example). I still set priorities on sounds (in the case with sound cards with low channels). I just can’t let 32 explosion sounds all be playing at once… it sounds awful after the first 5 or 6, and can’t be distinguished by the player anyway.
I use this exact technique in two published games and it works very well (the games are not written in Unity). In those cases, I can easily track when a sound finishes playing so I implement my own counts/limits per sound (I increment when playing, decrement when finished, and always check the current value before playing).
It looks like the “Min Time Between play” approximates this feature, but not closely. If there are three explosions that all go off on the same frame, I get 1 sound played. If those three are spread across several frames, I might get 2 or 3. In a case where there is a steady stream of explosions that fall on a time interval not evenly divisible by whatever I set for the “Min Time Between Play”, I will get 1 explosion punctuated occasionally by two overlapping. In the case of a “per sound limit” feature, I simply never would have more than 3 playing at once (if N = 3). It wouldn’t matter when they started, there just wound’t be more than 3 allowed to play at any one time. As soon as one finished a new one could be played.
Now I’m happy enough to enforce these limits myself if this isn’t a feature you are interested in implementing… assuming I can tell when a sound finishes playing. So my fallback question is simply “can I tell when a sound finished playing?” (hopefully via a callback, not with polling).
–Edit–
I’ll answer my own fallback question. It looks like you have a “completelyPlayedDelegate” on AudioObject. This checks the isPlaying member on the UnityEngine.AudioSource in Update(). This very conveniently encapsulates the “sound finished playing” concept in your framework. So worst case, I can run off an use this to implement my own per sound limits.
That’s correct, the completelyPlayedDelegate is called as soon as the audio was fully played.
I don’t get you point about the explosion sounds though. If your explosion is e.g. 2 seconds long and you set the MinTimeBetweenPlay to 0.5 then you will have 4 simultaneously playing explosion sounds at maximum. For our games this worked well.
Don’t get me wrong… having the MinTimeBetweenPlay is a great feature on a fantastic audio toolkit. It’s very useful in many cases, and I’ll be using it. While I’m at it, for anyone reading this and thinking about buying this toolkit… by all means do so. It will save you lots of coding on your own and is very fairly priced.
So, here’s a scenario:
Imagine I have two units in my strategy game. They are fighting the enemy and they fire their weapons at their own rates. Focus only on the explosions of their shells when they hit. With only two units, I expect to hear each shell explode. It doesn’t really matter when they hit… they could be 0.05 seconds apart or 1 second apart… I expect two sounds even if those sounds overlap most of the time. In this case, I might want a MinTimeBetweenPlay of 0. For sake of argument, lets say that 0.1 seconds is fine for MinTimeBetweenPlay, though. I can’t go much higher than that, else the case with two units produces explosion visuals that don’t have any accompanying explosion sound. I’m always forced to have a very small MinTimBetweenPlay because of the case with only 2 units firing.
Now, imagine I have 100 units. If the sound effects are 2 seconds long, I get 20 sounds playing at the same time. If they are 3 seconds it’s thirty. I can’t adjust the MinTimeBetweenPlay parameter to be higher so that I can limit the sounds, because of the case of just ‘2’ units.
Now imagine there are ten different weapons such that this is the case ten times over. Even 20 sounds per effect is too many… yet I can’t limit the number per effect by increasing the MinTimeBetweenPlay, else I ruin the scenario when there are only a few units on screen fighting.
That’s one scenario for having a per-effect max play limit. Now most of the time in most cases the sound effects are brief and 0.1 for MinTimeBetweenPlay is probably fine, and everything is probably ok most of the time. So I’m good with your toolkit at this point, as it provides what I need. Any special cases where I need to limit by count, I can handle on my own with your delegate.