0
votes

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.

1
Please explain your problem more. This one line question is not answerable. Which audio to stop and which one to play? - Programmer
Is this piece of code running on the-same GameObject each time or different GameObject? - Programmer
It is the same game object - Quicki
it's created every time when user clicks on a button - Quicki
I am sorry, I don't want add a useless answer. You should also post code that is calling that. Put them in a function like it is on your side. - Programmer

1 Answers

3
votes

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.