small problem with own music player script

hi everyone , i did some script for music player but i have only 1 slight problem that if i change the music before it finishes , the yield return new WaitForSeconds(w); don’t reset and causes the next music to cut out , but if i didn’t change the music manually all goes well , so how i can make the yield return new WaitForSeconds(w); reset after manually changing the music … here is the whole code (it could be very bad coding methods so any tips to optimize will be great)

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
using UnityEngine.EventSystems;

public class MusicPlayer : MonoBehaviour
{
    

	public AudioClip[] musics;
    public int i;
    public string nameOfClip;
    public Text creditsTextObject;
    public Animator animator;
    public Animator animator1;
	public Animator animator2;
	public bool showMenus;

	public Slider musicTime;
	public Slider musicVolume;

	public Text infoText;

	public float w;


	// Use this for initialization
	void Start () {
        i = 0;
        animator = animator.GetComponent<Animator>();
        animator.SetBool("ShowCredits", true);
        StartCoroutine(PlayMusics());
        StartCoroutine(CreditsPopup());
		musicVolume.value = 0.5f;
	}
	
	// Update is called once per frame
	void Update () {
		AudioSource audio = GetComponent<AudioSource>();
		musicTime.maxValue = audio.clip.length;
		musicTime.value = audio.time;
		audio.volume = musicVolume.value;
        if (i > musics.Length - 1)
        {
            i = 0;
            StartCoroutine(PlayMusics());
			w -= Time.deltaTime;
        }
		if (w <= 0) {
			
		}
		//if (EventSystem.current.IsPointerOverGameObject())
		if(Input.GetKeyDown(KeyCode.Tab)){
			showMenus = !showMenus;

			if (showMenus == true) {
				infoText.text = "Tab to Hide Controls";
			} else {
				infoText.text = "Tab to Show Controls";
			}
			if (showMenus == true) {
				{
					animator1.SetBool ("ShowSoundCtrl", true);
					animator2.SetBool ("ShowSoundCtrl1", true);
				}
			}
			else if (showMenus == false) {
       			{
            		animator1.SetBool("ShowSoundCtrl", false);
					animator2.SetBool("ShowSoundCtrl1", false);
        		}
			}
		}
	}

    IEnumerator PlayMusics(){
        AudioSource audio = GetComponent<AudioSource>();
        audio.clip = musics*;*
  •  w = audio.clip.length;*
    

creditsTextObject.text = musics*.name;*
audio.Play();
yield return new WaitForSeconds(w);
* i += 1;*
_ audio.clip = musics ;
* audio.Play ();
animator.SetBool (“ShowCredits”, true);
StartCoroutine (PlayMusics ());
StartCoroutine (CreditsPopup ());
}*_

IEnumerator CreditsPopup()
{
yield return new WaitForSeconds(20);
animator.SetBool(“ShowCredits”, false);
}

public void IncreaseVolume ()
{
AudioSource audio = GetComponent();
* musicVolume.value += 0.1f;*
}
public void DecreaseVolume()
{
AudioSource audio = GetComponent();
* musicVolume.value -= 0.1f;*
}
public void MuteVolume()
{
AudioSource audio = GetComponent();
if (audio.mute)
{
audio.mute = false;
}
else
{
audio.mute = true;
}
}

public void NextTrack()
{
AudioSource audio = GetComponent();
audio.Stop();
i += 1;
* w = audio.clip.length;*
animator.SetBool(“ShowCredits”, true);
StartCoroutine(PlayMusics());
StartCoroutine(CreditsPopup());
}

public void PrevTrack()
{
AudioSource audio = GetComponent();
audio.Stop();
i -= 1;
* w = audio.clip.length;*
animator.SetBool(“ShowCredits”, true);
StartCoroutine(PlayMusics());
StartCoroutine(CreditsPopup());
}

}

thanks for any help

Assign PlayMusics to a variable, so instead of this:

StartCoroutine(PlayMusics());

you’ll have this:

IEnumerator playMusicCoroutine = PlayMusics();

Then you can use:

StartCoroutine(playMusicCoroutine );

to start your Coroutine to play music and

StopCoroutine(playMusicCoroutine );

To stop your coroutine.

When you manually switch to next track, use StopCorutine to stop the current coroutine and music, and to play the next music, use StartCoroutine.

This should work. If anything works unintended, please let me know.:

 using System.Collections;
 using System.Collections.Generic;
 using UnityEngine;
 using UnityEngine.UI;
 using UnityEngine.EventSystems;
 
 public class MusicPlayer : MonoBehaviour
 {
     
 
     public AudioClip[] musics;
     public int i;
     public string nameOfClip;
     public Text creditsTextObject;
     public Animator animator;
     public Animator animator1;
     public Animator animator2;
     public bool showMenus;
 
     public Slider musicTime;
     public Slider musicVolume;
 
     public Text infoText;
 
     public float w;
 
    private IEnumerator playMusicCoroutine;
 
     // Use this for initialization
     void Start () {
         i = 0;
         animator = animator.GetComponent<Animator>();
         animator.SetBool("ShowCredits", true);
         playMusicCoroutine = PlayMusics();
         StartCoroutine(playMusicCoroutine);
         StartCoroutine(CreditsPopup());
         musicVolume.value = 0.5f;
     }
     
     // Update is called once per frame
     void Update () {
         AudioSource audio = GetComponent<AudioSource>();
         musicTime.maxValue = audio.clip.length;
         musicTime.value = audio.time;
         audio.volume = musicVolume.value;
         if (i > musics.Length - 1)
         {
             i = 0;
             StartCoroutine(playMusicCoroutine);
             w -= Time.deltaTime;
         }
         if (w <= 0) {
             
         }
         //if (EventSystem.current.IsPointerOverGameObject())
         if(Input.GetKeyDown(KeyCode.Tab)){
             showMenus = !showMenus;
 
             if (showMenus == true) {
                 infoText.text = "Tab to Hide Controls";
             } else {
                 infoText.text = "Tab to Show Controls";
             }
             if (showMenus == true) {
                 {
                     animator1.SetBool ("ShowSoundCtrl", true);
                     animator2.SetBool ("ShowSoundCtrl1", true);
                 }
             }
             else if (showMenus == false) {
                    {
                     animator1.SetBool("ShowSoundCtrl", false);
                     animator2.SetBool("ShowSoundCtrl1", false);
                 }
             }
         }
     }
 
     IEnumerator PlayMusics(){
         AudioSource audio = GetComponent<AudioSource>();
         audio.clip = musics*;*

w = audio.clip.length;
creditsTextObject.text = musics*.name;*
audio.Play();
yield return new WaitForSeconds(w);
i += 1;
audio.clip = musics ;
audio.Play ();
animator.SetBool (“ShowCredits”, true);
StartCoroutine(playMusicCoroutine);
StartCoroutine (CreditsPopup ());
}

IEnumerator CreditsPopup()
{
yield return new WaitForSeconds(20);
animator.SetBool(“ShowCredits”, false);
}

public void IncreaseVolume ()
{
AudioSource audio = GetComponent();
musicVolume.value += 0.1f;
}
public void DecreaseVolume()
{
AudioSource audio = GetComponent();
musicVolume.value -= 0.1f;
}
public void MuteVolume()
{
AudioSource audio = GetComponent();
if (audio.mute)
{
audio.mute = false;
}
else
{
audio.mute = true;
}
}

public void NextTrack()
{
AudioSource audio = GetComponent();
audio.Stop();
i += 1;
w = audio.clip.length;
animator.SetBool(“ShowCredits”, true);
StopCoroutine(playMusicCoroutine);
StartCoroutine(playMusicCoroutine);
StartCoroutine(CreditsPopup());
}

public void PrevTrack()
{
AudioSource audio = GetComponent();
audio.Stop();
i -= 1;
w = audio.clip.length;
animator.SetBool(“ShowCredits”, true);
StopCoroutine(playMusicCoroutine);
StartCoroutine(playMusicCoroutine);
StartCoroutine(CreditsPopup());
}

}

What fixed it for me is adding StopAllCoroutines (); to the manual switching functions.