- Home /
Using yield WaitForSeconds after AudioSource.PlayClipAtPoint
I am trying to play a sound (ticking) right before an explosion. the ticking sound will not play correctly if I use yield WaitForSeconds(), I will have a buzzing sound instead of a ticking one.
if(condition){
AudioSource.PlayClipAtPoint(exploTick,gameObject.transform.position);
yield WaitForSeconds(exploTick.length);
placeExplosion=Instantiate(electExplode,gameObject.transform.position,Quaternion.identity);
placeExplosion.enableEmission=true;
Removing "yield WaitForSeconds" will make the audio clip to play correctly.
Any thoughts?
Issues like 'yield" and "coroutines" are only for very advanced programmers. there is utterly no need to use them to do something so incredibly simple.
Just use "Invoke" which is the basic command used to program video games.
Thanks alucardj for giving me a hint. Finally I got it to work by testing and forcing the audio clip to play just once.
private var onePlay:boolean=false;
if(condition){
if(onePlay) //This will not evaluate for the first frame.The audio clip will play
return;
AudioSource.PlayClipAtPoint(exploTick,gameObject.transform.position);
onePlay=true; //Switch the value to true and the clip will never be played again
yield WaitForSeconds(exploTick.length);
placeExplosion=Instantiate(electExplode,gameObject.transform.position,Quaternion.identity);
placeExplosion.enableEmission=true;
Now the audio clip is playing as it should.
Answer by aldonaletto · Aug 21, 2012 at 01:42 PM
You can use a coroutine, but be sure to not call it more than once - or you will get that buzzing sound and a memory crowded by tons of coroutine instances:
var timerOn = false; var tickInterval: float = 0.5;
function TimeBomb(timer: float){ if (timerOn) return; // abort new calls to TimeBomb timerOn = true; // signal that TimeBomb is running while (timer > 0){ // while timer is counting... audio.Play(); // play the tick sound... yield WaitForSeconds(tickInterval); // and wait a decent interval timer -= tickInterval; // count the time elapsed } // timer zeroed - explode the bomb: placeExplosion = Instantiate(electExplode, transform.position, Quaternion.identity); placeExplosion.enableEmission=true; timerOn = false; // TimeBomb has finished } Add an AudioSource to the bomb and set its Clip field to the desired tick sound. Call TimeBomb(timeToExplode) when you want to start the timer. In order to avoid starting multiple TimeBomb coroutines, only call TimeBomb when timerOn is false (the coroutine already does that, but at that point a memory block was already allocated - if called each frame, a lot of unused memory blocks will be generated, causing more frequent garbage collections - a time consuming internal operation)
Thanks Aldo, well I did exactly what you have suggested but without adding an audio source:
private var onePlay:boolean=false;
if(condition){
if(onePlay) return;
AudioSource.PlayClipAtPoint(exploTick,gameObject.transform.position);
onePlay=true;
yield WaitForSeconds(5.0);
placeExplosion=Instantiate(electExplode,gameObject.transform.position,Quaternion.identity);
placeExplosion.enableEmission=true;}
Now everything plays nicely.