Quicki Quicki - 22 days ago 5
C# Question

Stop audio when is playing another one in Unity3D

How can I stop one audio when is playing another one?

public AudioSource audioSource;
public AudioClip audioClip;
private string[,] levelWords;
//public static string glupiaZmienna;
public Text txt;

public void OnPointerClick(PointerEventData eventData)
{
Debug.Log(gameObject.name);
WordsLoader w = new WordsLoader();
levelWords = w.wLevelWords;
SetCategoryButton scb = new SetCategoryButton();
int a = scb.Kategoria;
zupa();

AudioSource audio = gameObject.AddComponent<AudioSource>();
audio.Stop();
audio.clip = (AudioClip)Resources.Load(a+ "/" + WordsLoader.language + "/Sounds/" + gameObject.name);

audio.Play();


// txt = gameObject.GetComponent<Text>();
}

public void zupa()
{ WordsLoader w = new WordsLoader();
SetCategoryButton scb = new SetCategoryButton();
int a = scb.Kategoria;
print(w.wHowManyWords);

for (int i = 0; i < w.wHowManyWords; i++)
{
print("jestem tu");
if (levelWords[i, 0] == gameObject.name)
{
txt = GameObject.Find("Text").GetComponent<Text>(); ;
txt.text = levelWords[i, 2];
}

}
}


This code is in a script which start playing a sound after click a button. I would like stop earlier started audio.

Answer

EDIT: Answer has to change a-lot due to comments left under it. It makes sense to overwrite everything.

You need a reference that points to all the AudioSource. Store every ClickAction instance in a List, in another script(PlayerManager). Before you play the audio, loop through that List and stop playing it if it is playing. After that, you can then play your audio.

Also, you currently call Resources.Load each time you want to play the Audio. This is not good in terms of performance. You should do this once in the Start() function, then play it when it is needed. Also, your gameObject.AddComponent<AudioSource>() code should only be called once too.

Your new ClickAction script:

public class ClickAction : MonoBehaviour
{
    public AudioSource audioSource;
    public AudioClip audioClip;
    private string[,] levelWords;
    //public static string glupiaZmienna;
    public Text txt;

    public AudioSource clickAudioSource;
    PlayerManager playerManager = null;

    void Start()
    {
        //Get PlayerManager from PlayerManager GameObject
        playerManager = GameObject.Find("PlayerManager").GetComponent<PlayerManager>();
        clickAudioSource = gameObject.AddComponent<AudioSource>();
        clickAudioSource.clip = (AudioClip)Resources.Load(a + "/" + WordsLoader.language + "/Sounds/" + gameObject.name);

        //Register this Script to the PlayerManager 
        playerManager.addClickAction(this);
    }

    public void OnPointerClick(PointerEventData eventData)
    {
        Debug.Log(gameObject.name);
        WordsLoader w = new WordsLoader();
        levelWords = w.wLevelWords;
        SetCategoryButton scb = new SetCategoryButton();
        int a = scb.Kategoria;
        zupa();

        //Play Audio
        playAudio();

        // txt = gameObject.GetComponent<Text>();
    }

    private void playAudio()
    {
        playerManager.playAudio(clickAudioSource);
    }

    public void stopAudio()
    {
        //If not null and playing then stop audio
        if (clickAudioSource != null && clickAudioSource.isPlaying)
        {
            clickAudioSource.Stop();
        }
    }

    public void zupa()
    {
        WordsLoader w = new WordsLoader();
        SetCategoryButton scb = new SetCategoryButton();
        int a = scb.Kategoria;
        print(w.wHowManyWords);

        for (int i = 0; i < w.wHowManyWords; i++)
        {
            print("jestem tu");
            if (levelWords[i, 0] == gameObject.name)
            {
                txt = GameObject.Find("Text").GetComponent<Text>(); ;
                txt.text = levelWords[i, 2];
            }

        }
    }

    void OnDisable()
    {
        //Un-Register this Script from the PlayerManager when it is destroyed
        playerManager.removeClickAction(this);
    }
}

PlayerManager script. Create a GameObject called PlayerManager, then attach the script below to it:

public class PlayerManager : MonoBehaviour
{
    List<ClickAction> clickActions = new List<ClickAction>();

    public void addClickAction(ClickAction clickActionToAdd)
    {
        //Adds clickActionToAdd if it does not exist in the List already
        if (!clickActions.Contains(clickActionToAdd))
        {
            clickActions.Add(clickActionToAdd);
        }
    }

    public void removeClickAction(ClickAction clickActionToAdd)
    {
        //Removes clickActionToAdd if it exist in the List 
        if (clickActions.Contains(clickActionToAdd))
        {
            clickActions.Add(clickActionToAdd);
        }
    }

    public bool clickActionExist(ClickAction clickActionToAdd)
    {
        //Removes clickActionToAdd if it exist in the List 
        return clickActions.Contains(clickActionToAdd);
    }

    public void playAudio(AudioSource audSource)
    {
        //Stop Other Audio
        stopAllClickActionAudio();

        //Now, play the one that was passed in
        audSource.Play();
    }

    void stopAllClickActionAudio()
    {
        //Stop Audio on every ClickAction script
        for (int i = 0; i < clickActions.Count; i++)
        {
            clickActions[i].stopAudio();
        }
    }
}

When the playAudio function is called, it will stop all audio from AudioSource that is stored in the List, then it will play the current AudioSource that is passed into it.