- Home /
Coroutine problem
Hey,
I have an audio manager class that uses pooling to re-use audio clips, i have a method that checks if the clip is already present in the audio sources pool, if so it plays it, else it finds an empty slot to load the clip and play it.
I have a coroutine that stops an audio clip if it is found in the pool, over a period of time, fading it out.
My problem is that i don't know how to cancel my coroutine if the same clip being faded out needs to be replayed, it will be replayed while continuing to be faded out.
I'm guessing that i have to use "StopCoroutine" but i don't understand how to do it.
Some help would be appreciated.
public void PlaySound(AudioClip newClip, float newVolume, float newPitch)
{
for (int i = 0; i < poolSize; i++)
{
//If the clip already exist, we re-use it
if (audioSources[i].clip == newClip)
{
audioSources[i].pitch = newPitch;
audioSources[i].volume = newVolume;
audioSources[i].Play();
return;
}
}
}
public IEnumerator StopSound(AudioClip newClip, float fadeOutSpeed)
{
for (int i = 0; i < poolSize; i++)
{
//If audio clip is found, stop it with a fade out
if (audioSources[i].clip == newClip)
{
while (audioSources[i].volume > 0)
{
audioSources[i].volume -= fadeOutSpeed;
yield return null;
}
audioSources[i].Stop();
audioSources[i].clip = null;
yield return null;
}
}
}
Also my audio manager is a singleton, here is how i start the coroutine from other scripts
Audio$$anonymous$$anager.instance.StartCoroutine(Audio$$anonymous$$anager.instance.StopSound(someSound, 2));
Answer by jdean300 · Mar 07, 2017 at 02:37 AM
To use StopCoroutine, you need to save the call to your coroutine method:
// as a variable in the singleton
IEnumerator audio;
// In your method where you start the coroutine
audio = AudioManager.instance.StopSound(someSound, 2);
AudioManager.instance.StartCoroutine(audio);
// and then to cancel/stop that coroutine early
StopCoroutine(audio);
Thanks for helping,
The coroutine is started from other scripts directly, not from a method within the audio manager class, should i do that ins$$anonymous$$d?
I don't think it should matter. You can store the IEnumerator variable anywhere you want.
What i don't understand is how to stop the coroutine only if the clip passed in PlaySound is the one being faded out in the coroutine, and how to stop this coroutine only, not the other sounds fading out, maybe i simply didn't understand your suggestion?
I'm trying to have my audio manager handle this so that when PlaySound is called it takes care automatically of stopping the couroutine if it is running with the sound that is trying to play in PlaySound.
When you say //Wherever you start the clip, does this mean that i would need a stopSoundRoutines dictionary in every scripts that uses PlaySound?
No... you need to use it in PlaySound. So put the dictionary in the Audio$$anonymous$$anager script and create a new method on the Audio$$anonymous$$anager like the following:
public void StopSound(AudioClip newClip, float fadeOutSpeed) {
stopSoundRoutines[newClip] = StopSoundInternal(newClip, fadeOutSpeed);
}
// Notice I made StopSound private and renamed it
private IEnumerator StopSoundInternal(AudioClip newClip, float fadeOutSpeed){
// Old StopSound code goes here
}
I can't give you the exact code to use character by character. I don't know how the rest of your code is structured and that's not very helpful anyways.
I'm pretty new to coding and have never used dictionaries before so this is getting a bit complicated for me, for example i don't understand how you start StopSoundInternal since i'm not seeing any "StartCoroutine" in your public StopSound method. Other than that i think i understand what is happening.
I'll just sleep it off and start again fresh tomorrow, my brain just isn't working anymore, i really appreciate the help.
Yeah i figured it out, it seems to work perfectly, thank you so much!
Your answer
Follow this Question
Related Questions
Can't call StopCoroutine function from another script. 1 Answer
If I StopCoroutine("myCoroutine")', will the variable values in myCoroutine be reset? 1 Answer
How to force Coroutine to finish 1 Answer
I'm stopping coroutines in pause but can't bring them back 0 Answers
Reset a coroutine on event 1 Answer