Best way to play intermittent random sounds

Whats the best way to play intermittent random sounds? I came up with this, but dont think its very efficient, can it be done better?

public void ZombieMoan()
    {
        int randomZombieNoise = Random.Range(1, 1000);
        switch (randomZombieNoise)
        {
            case 199:
                audioData = GetComponent<AudioSource>();
                audioData.Play(0);
                break;
        }
       
    }
  • @warrenbrandt *
    “Whats the best way to play intermittent random sounds?”

What is the context?

Just pick the random sound from a list, using random range from 0 to list length.

Think about it - are you really going to have a if/switch of 200 cases, when you want to pick random choice?

You could create a list of random ambient sounds, then play these with random delay, but only start playing next sound after certain time has passed (with some random offset) and optionally only when the previous sound has stopped playing.

1 Like

This is a very basic example of random intermittence and random clip selection.

So:
We cache the audio source reference at start, we don’t fetch it every time we need it, we just fetch it once.
If there is no clip currently playing, we check to see if the wait time has elapsed.
If the wait time has not yet elapsed, we continue to count it down.
If the wait time has elapsed, then we fetch a random audio clip from the list, assign it the source, and play it, and then we generate a new random wait time.

public class RandomSounds : MonoBehaviour
{
    public List<AudioClip> audioClips;
    public AudioClip currentClip;
    public AudioSource source;
    public float minWaitBetweenPlays = 1f;
    public float maxWaitBetweenPlays = 5f;
    public float waitTimeCountdown = -1f;

    void Start()
    {
        source = GetComponent<AudioSource>();
    }

    void Update()
    {
        if (!source.isPlaying)
        {
            if (waitTimeCountdown < 0f)
            {
                currentClip = audioClips[Random.Range(0, audioClips.Count)];
                source.clip = currentClip;
                source.Play();
                waitTimeCountdown = Random.Range(minWaitBetweenPlays, maxWaitBetweenPlays);
            }
            else
            {
                waitTimeCountdown -= Time.deltaTime;
            }
        }
    }
}
5 Likes

thanks guys

Thank you so much Hikiko66, this script is fantastic!!! It does exactly what I need, play a sound file from beginning to end and then playing the next one with a random time delay inbetween. This is perfect for environments, like bird sounds and so on.

If it helps anyone, to make this work, you only need a single gameObject and then add an Audio Source component to it as well as the script. Then, drag this very gameObject onto itself into the “Source” part of the script in the inspector. All the audio files to play go into the script section as well, the audio component itself does not need an audio file and is only there so that you can do things like 3D spacial changes for example. I first made the mistake that I created 2 separate gameObjects, one to hold the script, and one to hold the audio source component. I then dragged that second gameObject onto the “Source” in the first gameObject that held the script. This caused the Source to be automatically removed on runtime, resulting in my sounds not playing at all.

Thank you Everyone!

I solved this using a Coroutine instead.

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class RandomBird : MonoBehaviour
{
    [SerializeField] private AudioClip[] clips;
    [SerializeField] private float frequencyMin;
    [SerializeField] private float frequencyMax;

    private AudioSource audioSource;


    // Start is called before the first frame update
    void Start()
    {
        audioSource = GetComponent<AudioSource>();
        StartCoroutine(RandomPlayer());
    }

    private IEnumerator RandomPlayer()
    {
        float waitTime;
        while (true)
        {
            waitTime = Random.Range(frequencyMin, frequencyMax);
            yield return new WaitForSeconds(waitTime);
            PlayRandomSound();
        }
    }

    private void PlayRandomSound()
    {
        int soundIdx = Random.Range(0, clips.Length);
        audioSource.PlayOneShot(clips[soundIdx]);
    }

}
1 Like