The best way to randomize sounds in Unity 3D C#
By Victor Engström
The worst random
To make the most out of the sounds in a game you want to have the least repetition and most variation. The most basic way to do this is to have a random sound selection like this:
// The worst random audioSource.clip = audioClipArray[Random.Range(0, audioClipArray.Length)];
Why is this a problem?
The Random.Range is a problem because its true random and does not care if it plays sound number 1 five times in a row:
Possible outcome: 1, 1, 1, 1, 1
This can lead to where you get the same sound repeating after itself any number of times.
How to make a better random
One way to make the random better is to remember the last selected value and retry the random if gets that one next time. The problem with this is that you can get very repetitive variations anyway.
// The better but not best random
while (audioSource.clip == lastAudioClip) {
audioSource.clip = audioClipArray[Random.Range(0, audioClipArray.Length)];
}
lastAudioClip = audioSource.clip;The worst-case scenario here is that you’d get sound alternating between two variations even if you had more. Like the example below:
Possible outcome 1, 2, 1, 2, 1
The best way
The best way I’ve found is to remember half the length of the possible variations.
(Updated 2026 01 31 with improvements)
using UnityEngine; [System.Serializable] public class RandomAudioClip : MonoBehaviour { public AudioClip[] audioClips = new AudioClip[0]; private int[] previousIndexes = new int[0]; private int currentIndex; // The best random method public AudioClip GetRandomAudioClip() { if (audioClips.Length == 0) { return null; } int randomIndex = 0; // Sets the length to half of the number of AudioClips // This will round downwards, so it works with odd numbers like 3 // Check every time so it wont break if changing the length in runtime if (previousIndexes.Length != audioClips.Length / 2) { previousIndexes = new int[audioClips.Length / 2]; currentIndex = 0; } if (previousIndexes.Length > 0) { // Pseudo random function remembering which clips it last played to avoid repetition // Max 40 retries giving you a 0,0000000000009 probabiltiy of repetition for (int i = 0; i < 40; i++) { randomIndex = Random.Range(0, audioClips.Length); if (!PreviousIndexesContain(randomIndex)) { break; } } previousIndexes[currentIndex] = randomIndex; // Wrap index currentIndex++; if (currentIndex >= previousIndexes.Length) { currentIndex = 0; } } return audioClips[randomIndex]; } public bool PreviousIndexesContain(int randomIndex) { for (int i = 0; i < previousIndexes.Length; i++) { if (previousIndexes[i] == randomIndex) { return true; } } return false; } }
This way if the array is 4 AudioClips (remembering the last two) it could pick:
Possible outcome 1, 3, 2, 1, 4, 3
The problems with the worst-case scenarios of the other random ways are not present in this way of randomization.
Conclusion
Sure, it’s a bit of work to set up, but it sounds way better. Also, not even the big shots like Fmod uses this better random, they use the random where you remember the last played sound and not multiple which can yield bad sounding results.
Happy randomization!
Victor Engström
Simon
Hey!
Thanks for the tutorial! I just implemented this in one of my Unity projects, and it saved me quite some time not having to optimize randomization myself. Works pretty damn well so far!
One thing I noticed was when using an array with 3 clips, you might still end up with two clips alternating. I’m guessing this is due to the previousArray rounding down and ending up with only 1 remembered clip.
Still a really useful piece of code I’ll be using for my audio implementation!
Sonigon
Glad to help mate 🙂
Its is supposed to round down, but you probably easily could change it yourself to round up if you’d want! 🙂