My simple AudioRandomiser class

Here ya go. Add the script as a component onto your sub-components, populate the list of sound effects manually, and have all your UnityEvents call PlayRandomisedSound() instead of Play().

using UnityEngine;

namespace RPG.Sound
{
    public class SoundRandomiser : MonoBehaviour
    {
        [SerializeField] float lowerPitchRange = 0.8f;
        [SerializeField] float upperPitchRange = 1.2f;
        [SerializeField] AudioClip[] soundSet = null;
        AudioSource audioSource = null;

        private void Awake()
        {
            audioSource = GetComponent<AudioSource>();
        }

        public void PlayRandomisedSound()
        {
            // Set the clip to be a random one from the set
            audioSource.clip = soundSet[Mathf.RoundToInt(Random.Range(0, soundSet.Length - 1))];
            // Set the pitch to a random value within the specified range.
            audioSource.pitch = Random.Range(lowerPitchRange, upperPitchRange);

            audioSource.Play();
        }
    }
}

Happy developing!

You don’t need all this. The overload for Random.Range that take integers (as this one does) will return an integer, and it excludes the max. With this code, the last clip will never be selected because you are restricting the range even further by subtracting 1. If there are 3 clips, you are telling it to select between 0 inclusive and 2 (3 clips - 1) exclusive so it will only select between 0 and 1. Clip 2 (the third one) will never be selected.
All you need is

audioSource.clip = soundSet[Random.Range(0, soundSet.Length)];

The Random.Range you used for pitch works as you expected, because you are passing it float values. The overload that accepts float selects a float between min inclusive and max inclusive

Apart from that, nicely done.

1 Like

You know, it’s funny, I had it without the rounding for the first submission, then I was reading over it and quickly “fixed” it. :sweat_smile:

1 Like

It’s an easy thing to mix up, as it seems counterintuitive that ints and floats would behave differently. It was done this way, however, specifically so that we could use the length/count of a collection as the upper range and still get a zero based index within the result set.

Not counterintuitive at all. Floating point decimals and integers need to behave differently. What I didn’t expect was the overload that made Random.Range return an int value. I’m used to getting a random float under one and multiplying by the range of random number I actually want - Unity made it so easy I second guessed myself and messed up. I’m probably around your age, Brian, and I have a lifetime of not-coding-specific IT work at my back, it’s just a matter of un-learning old habits that don’t apply in newer languages / environments.

Privacy & Terms