C# - Random Audioclip - Ressources.Load

Hey guys,

I can’t figure out how to associate audioclip to gameobjects randomly.
Let’s just assume we have 2 gameobjects and 2 audioclip.
The gameobjects have Audio Sources, but no audio in it.

On runtime i want to be able to give them an audioclip.
I’m strugling now with the AudioClip[ ] stuff.

Here is my code (attached to my camera for testing)

using UnityEngine;
using System.Collections;

public class GameManager : MonoBehaviour {

    public AudioClip[] audioArray;

    // Use this for initialization
    void Start () {
   
        audioArray =  new AudioClip[]{
            (AudioClip)Resources.Load(son1),
            (AudioClip)Resources.Load(son2),
    };

    }
   
    // Update is called once per frame
    void Update () {
   
        audio.clip = audioArray[Random.Range(0, audioArray.Length)];
        audio.Play ();

    }
}

No sound playing at all, and no error

What am i doing wrong ?

Thanks a lot !

You are doing it in update
every frame it is assigning the clip, and then playing from the beginning, giving you one frame of the silence at the start of the track.

1 Like

Hey,

Thanks for the answer !
I changed it but it still doesn’t work… No error and no sound… :confused:

using UnityEngine;
using System.Collections;

public class GameManager : MonoBehaviour {
  
    public AudioClip[] audioArray;
  
    // Use this for initialization
    void Start () {

        audioArray =  new AudioClip[]{
            (AudioClip)Resources.Load("son1"),
            (AudioClip)Resources.Load("son2"),
        };
        audio.clip = audioArray[Random.Range(0, audioArray.Length)];
        audio.Play ();
    }
  
    // Update is called once per frame
    void Update () {
      

      
    }
}

Which of the following obvious things have you checked?
Speakers on and volume up?
Object has audio source
Scene has audio Listener
Clips are in Resources folder
Clips are not null after loading

Hey,

Thanks, not sure what was wrong (my speakers were definitely on :p).

Thank you

Your folder is named Ressources instead of Resources so nothing is being loaded into the array.

You also have 2 AudioSources on your GameObject, which isn’t necessary.

Hey,

Yes i figured i tout, thank you ! :slight_smile:
Now i would like to pick a music from the array, and then remove it from the array (or at least it doesn’t have to be available anymore).

I was thinking of removing Choice1 from the Random.Range() but i couldn’t find how to do it.
I tried with a do while loop (while Choice2 = Choice1 pick a random number). It works.
Not sure it is the best way to do it… ?

public class GameManager : MonoBehaviour {
  
    public AudioClip[] audioArray;
    public AudioClip music1;
    public AudioClip music2;
    public AudioClip music3;
    private int Choice1;
    private int Choice2;
    private int Choice3;

    // Use this for initialization
    void Start () {

        int Choice1 = Random.Range (0, audioArray.Length);
        Debug.Log (Choice1);

        do{
            Choice2 = Random.Range (0, audioArray.Length);

        }while (Choice2 == Choice1)
                        ;

        do{
            Choice3 = Random.Range (0, audioArray.Length);
          
        }while (Choice3 == Choice1 || Choice3 == Choice2)
                        ;

        audioArray =  new AudioClip[]{
            (AudioClip)Resources.Load("son1"),
            (AudioClip)Resources.Load("son2"),
            (AudioClip)Resources.Load("son3"),
        };

        music1 = audioArray [Choice1];
        music2 = audioArray [Choice2];
        music3 = audioArray [Choice3];
        audio.PlayOneShot (music3);

    }
  
    // Update is called once per frame
    void Update () {
  
        Debug.Log (Choice3);
      
    }
}

Thanks,

To go for exactly what you are saying it would be like this

public AudioClip[] audioArray;
    public AudioClip music1;
    public AudioClip music2;
    public AudioClip music3;

    // Use this for initialization
    void Start () {
  
        audioArray =  new AudioClip[]{
            (AudioClip)Resources.Load("son1"),
            (AudioClip)Resources.Load("son2"),
            (AudioClip)Resources.Load("son3"),
        };

        List<AudioClip> tempClips = new List<AudioClip>(audioArray);
        int index = Random.Range(0,clips.Count);
        music1 = tempClips [ index ];
        tempClips.RemoveAt( index );

        index = Random.Range(0,clips.Count);
        music2 = tempClips [ index ];
        tempClips.RemoveAt( index );

        index = Random.Range(0,clips.Count);
        music3 = tempClips [ index ];
        tempClips.RemoveAt( index );

        audio.PlayOneShot (music3);
    }
}

But it would be tempted to just load then shuffle the array, then always take the first element (or last)

Thank you ! I don’t know what tempclips are and how index works, so i’ll keep using my script for now :slight_smile:
I’ll definitely take a look at your code when i’m less tired !

I’m trying to access one of these random audioclips from another script and it don’t work :

using UnityEngine;
using System.Collections;

public class Planet1Sound : MonoBehaviour {

    private AudioClip myPlanetSound1;
    private GameObject myCamera;

    // Use this for initialization
    void Start () {
                  myCamera = GameObject.Find ("myCamera");
              }

    // Update is called once per frame
    void Update () {
   
            myPlanetSound1 = myCamera.GetComponent<GameManager> ().music1;

            Debug.Log (myPlanetSound1);

    }

My Debug.log is always null. I dont understand why.
I define music1 at runtime in my GameManagerScript, so it shouldn’t be null…

Log out myCamera, to see if the object is being found
then log out the getted component to check that, etc