Chen Ji
Chen Ji

Reputation: 41

How to play the audio one by one in unity

I want to achieve playing the music one by one in Unity. I tried to create an audioClip array and want to play them one by one. And i also tried to use StartCoroutine to wait one song finished and then playing the next.

I tried to create an audioClip array and want to play them one by one. And i also tried to use StartCoroutine to wait one song finished and then playing the next.

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

[RequireComponent(typeof(AudioSource))]
public class AudioManager : MonoBehaviour {

    public AudioClip[] _audioClips;
    private AudioSource _audioSource;

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


    // Use this for initialization
    void Start () {

        for (int i = 0; i < _audioClips.Length;i++){
            _audioSource.PlayOneShot(_audioClips[i]);
            StartCoroutine("WaitForMusicEnd");
        }
    }

    IEnumerator WaitForMusicEnd()
    {
        while (_audioSource.isPlaying)
        {
            yield return null;
        }
    }

}

However, the music will play at the same time. Please help!

Upvotes: 1

Views: 2241

Answers (1)

zambari
zambari

Reputation: 5035

you are not too far off, but this is not how coroutine work - you need to be insde a coroutine to be able to wait, here's how you do it

void Start ()
     {
        StartCoroutine(PlayMusic());
     }

IEnumerator PlayMusic()
  {
      for (int i = 0; i < _audioClips.Length;i++)
      {
        _audioSource.PlayOneShot(_audioClips[i]);
         while (_audioSource.isPlaying)
                yield return null;
     }
  }

The control flow goes like this:

void Start()
{
  StartCoroutine(Foo());
  StartCoroutine(Bar());
}
IEnumerator Foo()
{
  Debug.Log("FOO");
  yield return null;
  Debug.Log("foo");
}
IEnumerator Bar()
{
  Debug.Log("BAR");
   yield return null;
   Debug.Log("bar");
}


// FOO
// BAR
// foo
// bar

If you watch what happens: With each coroutine start, the control goes into the coroutine, up until the first yield return. At this point we rewind the instruction pointer back to Start(), and start the second coroutine. Then Start() finishes, the frame is drawn. Unity keeps track of running coroutines, and before next frame will return control to where you left within your coroutine.

Its quite clever, as it makes spreading things in time much easier.

Upvotes: 1

Related Questions