I am trying to create a Music button and each time this button is pressed the song will change. In total, I have 4 songs. So, when the button is pressed the 1st time, song 1 will play. When the button is pressed for the 2nd time, song 2 will play and so on.
The user can change the song at any point they like. So if the user decides to change the song in the middle of playing a song, they can simply press the button and the next song will start to play.
If the user does NOT press the button, the song which they are currently listening to, will keep on playing until they press the button.
I have tried to create an array of AudioClips and wrote a piece of code the loops through the array. However, only the first song will play each time I press the button. Can anyone help me to resolve this issue, please?
I am aware that I am calling StartCoroutine(PlayClips()); on the method which the button is attached to. But if I just simply move the code to the method CallMethod(), Unity gets stuck.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System;
public class Snow_Mountain : MonoBehaviour
{
/*public GameObject OpenOptsCanvas;
public GameObject UserOptsCanvas;*/
/*public AudioClip song1;
public AudioClip song2;
public AudioClip song3;
public AudioClip song4;*/
public AudioClip[] clips;
public AudioSource source;
int buttonpress = 0;
int i;
// Start is called before the first frame update
void Start()
{
}
// Update is called once per frame
void Update()
{
}
IEnumerator PlayClips()
{
for (i = 0; i < clips.Length; i )
{
source.clip = clips[i];
//source.clip = clips[clips.Length];
source.Play();
print("I:" i);
print("Clips Lenght:" clips.Length);
//Play songs from begging
if (i == clips.Length)
{
i -= clips.Length;
print("Clips Lenght:" clips.Length);
}
while (source.isPlaying)
{
yield return null;
}
}
}
/*private void Button1_Click(object sender, EventArgs e)
{
buttonpress ;
print("Button Press: " buttonpress);
i ;
print("I:" i);
}*/
public void CallMethod()
{
StartCoroutine(PlayClips());
}
}
CodePudding user response:
You need to increment song counter out of the method; therefore, when it's called it goes to the next song and not just starting the same loop again. You can create an IEnumerator property in your code, and stop and start it when a song is ended or the next button is clicked:
public AudioClip[] clips;
public AudioSource source;
private int _songCounter = -1;
private IEnumerator _playSongEnumerator;
private void Start()
{
SongEnded();
}
private IEnumerator PlayClips(Action songEnded)
{
source.clip = clips[_songCounter];
source.Play();
while (source.isPlaying)
{
yield return null;
}
songEnded.Invoke();
}
private void SongEnded()
{
// so you don't exceed the array length
_songCounter = (_songCounter 1) % clips.Length;
if (_playSongEnumerator != null) StopCoroutine(_playSongEnumerator);
_playSongEnumerator = PlayClips(SongEnded);
StartCoroutine(_playSongEnumerator);
}
public void CallMethod()
{
SongEnded();
}