- Home /
How to play a playlist of mp3s randomly?
I have looked through the forums and there were many answers which I tried but I keep getting conversion errors between AudioClip and AudioSource for some reason! I may not be new to programming but I am new to how things are done in Unity and was hoping for some help. Here is all the code I have written, I have even dragged my 3 mp3s into myMusic Array in the inspector but I keep getting Array index is out of range or Object reference not set to an instance of an object. All of my music is located in Assets/Music/ folder.
using UnityEngine;
using System.Collections;
public class Music : MonoBehaviour {
public AudioSource audio;
public AudioClip[] myMusic = new AudioClip[3];
// Use this for initialization
void Awake () {
myMusic = Resources.LoadAll("Music",typeof(AudioClip)) as AudioClip[];
audio.clip = myMusic[0] as AudioClip;
}
void Start (){
audio.Play();
}
// Update is called once per frame
void Update () {
if(!audio.isPlaying)
playRandomMusic();
}
void playRandomMusic()
{
audio.clip = myMusic[Random.Range(0,myMusic.Length)] as AudioClip;
audio.Play();
}
}
does it play when you direct it to just a specific file? Its difficult to locate the bug cause, it might be that the resources are not loaded at tall, which means the array is null, and thats the error. Try playing it directly with just 1 audio which you know IS there.. then add these to an array using the above method.
Pretty sure you don't need 'as AudioClip' in there at all
You may be populating values in the inspector, but you're overwriting them in Awake(). If you want to use the inspector values, get rid of line 10 (the Resources.LoadAll call).
Answer by aldonaletto · Nov 04, 2013 at 10:52 PM
First of all, add an AudioSource component to the object via menu Component/Audio/Audio Source, and delete the AudioSource declaration in your code (audio is a GameObject property). Change also the declaration of myMusic to Object[] (that's what LoadAll returns), and don't initialize it (there's no need). Finally, remove the type coercion from LoadAll (you can't coerce type of entire arrays this way). The code would become this:
using UnityEngine;
using System.Collections;
public class Music : MonoBehaviour {
Object[] myMusic; // declare this as Object array
void Awake () {
myMusic = Resources.LoadAll("Music",typeof(AudioClip));
audio.clip = myMusic[0] as AudioClip;
}
void Start (){
audio.Play();
}
// Update is called once per frame
void Update () {
if(!audio.isPlaying)
playRandomMusic();
}
void playRandomMusic() {
audio.clip = myMusic[Random.Range(0,myMusic.Length)] as AudioClip;
audio.Play();
}
}
NOTE: The audio clips must be inside a folder Resources/Music, or LoadAll won't find them.
Hi, thanks for the help! The NOTE especially fixed my array index out of bounds error (from 0 songs being loaded) and Object[] type.
Thanks for this outstanding solution!
I would actually propose to not use the Resources Folder here, as it slows down your project a bit. Escpecially if you have songs in the folder that you don't use. Unity will use them in the build even if they are not used.
Also you might want to start with a random song? Here my suggestion:
public AudioSource myAudio;
public AudioClip[] my$$anonymous$$usic; // declare this as Object array
void Start()
{
playRandom$$anonymous$$usic();
}
// Update is called once per frame
void Update()
{
if (!myAudio.isPlaying)
playRandom$$anonymous$$usic();
}
void playRandom$$anonymous$$usic()
{
myAudio.clip = my$$anonymous$$usic[Random.Range(0, my$$anonymous$$usic.Length)] as AudioClip;
myAudio.Play();
}
@max_aigneraigner Thanks for the suggestion to reduce issues at build time. What I'm not sure is how you're loading the audio files to the AudioClip array. I see @aldonaletto solution loads from the resources folder, but you mentioned that's not efficient? Can you share how you would load the music files into the array?
public AudioClip[] my$$anonymous$$usic;
This line creates an exposed array in the editor. On the GameObject with your $$anonymous$$usic behavior, you can then fill in the array with audio files directly. This should be faster than loading them from the Resources folder at runtime, since the loading will be handled automatically by Unity.
I followed this "Resources.LoadAll" approach and it was a horrible idea because it takes a really really long time just to load a few tracks, causing 5 extra seconds of load time to start or load a game. Instead, just have array of AudioClip and then drag/drop them in the Unity Editor, no need to put the tracks in Resources folder.
Edit: Also, clearly I should've read the comments first :P
Your answer
Follow this Question
Related Questions
C sharp cant play Audio 2 Answers
How do I setup music for optimal playback on iOS? 0 Answers
Loop GetSpectrumData() through a song 2 Answers
Unity Unable to Reassign Audio Clip 1 Answer
How to stop music from restarting when reloading scene it began? 0 Answers