- Home /
How can I play a sound in sync with a countdown?
I am trying to make a sound play based on the time left before a grenade explodes. When the boolean "pinPulled" is set to true a float starts counting down from 3.5 seconds. I would like the sound to play once every second until the last second when I want the sound to loop, so it beeps at a faster rate. Because there are other sounds that also use this audio source (grenade explosion sound, grenade throw sound etc), I assign the grenade beep sound dynamically before playing it. Below is a part of the script, the sound gets assigned properly based on the time but for some reason it doesn't actually play. Any ideas how I should do this?
I've also tried using Invoke, yield waitforseconds and a while loop but they all give inconsistent timing.
simply use Invoke to do this sort of thing. It's incredibly easy to "script" games with it
Invoke( "aBeep", 1 );
Invoke( "aBeep", 2 );
Invoke( "aBeep", 3 );
Invoke( "finalWarning", 3 );
Invoke( "aBeep", 4 );
Invoke( "openGates", 4 );
Invoke( "aBeep", 5 );
Invoke( "beginAI", 5 );
Invoke( "startEngines", 5 );
you see? ultra-easy.
Answer by aldonaletto · May 25, 2013 at 05:01 PM
The problem is that you're calling Play repeatedly when fuseTimer is lower than 2.5s: Play restarts the sound each time it's called, thus if the sound has an initial pause or a slow attack nothing will be heard. You could call Play only once each time you cross a limit, like this:
var pinPulled : boolean = false;
var fuse : float = 3.5;
var fuseTimer : float = 0;
var grenadeBeep : AudioClip;
private var nextTime : float = -1; // declare this variable outside any function
//If a grenade's pin has been pulled, start the countdown
if (pinPulled) {
fuseTimer -= Time.deltaTime;
}
else { // pin in place: reset fuseTimer and nextTime
fuseTimer = fuse;
nextTime = fuseTimer - 1.0; // first tick one second after pin pulled
}
if (fuseTimer <= nextTime) { // it's time to tick:
nextTime = fuseTimer - 1.0; // set next tick to 1 second ahead
if (nextTime < 0){ // if entered fast range (last second), set loop
audio.loop = true;
}
audio.clip = grenadeBeep;
audio.Play(); // call Play only once
}
Brilliant! But in the last second the loop isn't actually making the beep speed up. How could I in the last second make the beep happen every half a second ins$$anonymous$$d of every second?
It should beep continuously, since loop is set during the last second. Anyway, you could change the code a little and implement a fast pace in the last second:
var pinPulled : boolean = false;
var fuse : float = 3.5;
var fuseTimer : float = 0;
var grenadeBeep : AudioClip;
var slowInterval : float = 1.0; // slow speed
var fastInterval : float = 0.2; // fast speed
private var nextTime : float = -1; // declare this variable outside any function
//If a grenade's pin has been pulled, start the countdown
if (pinPulled) {
fuseTimer -= Time.deltaTime;
}
else { // pin in place: reset fuseTimer and nextTime
fuseTimer = fuse;
nextTime = fuseTimer - slowInterval; // set time for 1st tick
}
if (fuseTimer <= nextTime) { // it's time to tick:
if (fuseTimer < 1.0){ // if entered fast range (last second), use fast interval
nextTime -= fastInterval;
} else { // otherwise beep at slow interval
nextTime -= slowInterval;
}
audio.clip = grenadeBeep;
audio.Play(); // call Play only once
}
Your answer
![](https://koobas.hobune.stream/wayback/20220613102913im_/https://answers.unity.com/themes/thub/images/avi.jpg)