Search Unity

Countdown timer with sound

Discussion in 'Scripting' started by Kovenant, Mar 26, 2015.

  1. Kovenant

    Kovenant

    Joined:
    Sep 18, 2013
    Posts:
    254
    I'm trying to make a script that will play a sound when the Round Timer hits 3, until it has reached 0.. A voice speaking "3...2...1...", but my script won't work the way I want it to..

    The first sound will play.. 58 times in a row... ;) How can this be fixed? I guess it's my IEnumerator StartCountdown() function that's broken?

    Here it is:
    Code (CSharp):
    1. using UnityEngine;
    2. using UnityEngine.UI;
    3. using System.Collections;
    4.  
    5. [RequireComponent(typeof(AudioSource))]
    6. public class RoundTimer : MonoBehaviour {
    7.  
    8.     public static RoundTimer rt;
    9.  
    10.     public Text textElement;
    11.     public int countDownSeconds = 120;
    12.     public int freezeTime = 4;
    13.     public AudioClip roundsUpSound;
    14.    
    15.     public AudioClip[] countdownSound;
    16.  
    17.     [HideInInspector] public float startTime;
    18.     private int restSeconds;
    19.     private int roundedRestSeconds;
    20.     private int displaySeconds;
    21.     private int displayMinutes;
    22.  
    23.     private bool timesUp = false;
    24.     private bool updateTime = true;
    25.     private bool startCount = false;
    26.  
    27.     void Awake()
    28.     {
    29.         startTime = Time.time;
    30.     }
    31.  
    32.     void Update()
    33.     {
    34.         float guiTime = Time.time - startTime;
    35.         restSeconds = countDownSeconds - ((int)guiTime);
    36.        
    37.         roundedRestSeconds = Mathf.CeilToInt (restSeconds);
    38.         displaySeconds = roundedRestSeconds % 60;
    39.         displayMinutes = roundedRestSeconds / 60;
    40.  
    41.         if (restSeconds == 0) {
    42.             timesUp = true;
    43.             startCount = false;
    44.             StartCoroutine (RoundsUp ());
    45.         } else {
    46.             timesUp = false;
    47.         }
    48.  
    49.         if (restSeconds == 3) {
    50.             startCount = true;
    51.             StartCoroutine (StartCountdown ());
    52.         }
    53.  
    54.         if (!timesUp && updateTime)
    55.             UpdateTime ();
    56.  
    57.     }
    58.  
    59.     void UpdateTime()
    60.     {
    61.         if (SpawnManager.spawn.freeze) {
    62.             startTime = Time.time;
    63.             textElement.color = SpawnManager.spawn.freezeColor;
    64.             textElement.text = string.Format ("{0:00}:{1:00}", displayMinutes, displaySeconds);
    65.         } else {
    66.             textElement.color = SpawnManager.spawn.normalColor;
    67.             textElement.text = string.Format ("{0:00}:{1:00}", displayMinutes, displaySeconds);
    68.         }
    69.     }
    70.  
    71.     IEnumerator StartCountdown()
    72.     {
    73.         if (startCount) {
    74.             Debug.Log(restSeconds);
    75.             if(restSeconds == 3) {
    76.                 SpawnManager.spawn.GetComponent<AudioSource> ().PlayOneShot (countdownSound [0]);
    77.             } else if(restSeconds == 2) {
    78.                 SpawnManager.spawn.GetComponent<AudioSource> ().PlayOneShot (countdownSound [1]);
    79.             } else if(restSeconds == 1) {
    80.                 SpawnManager.spawn.GetComponent<AudioSource> ().PlayOneShot (countdownSound [2]);
    81.             } else {
    82.                 startCount = false;
    83.             }
    84.         }
    85.         yield return new WaitForSeconds(0f);
    86.         UpdateTime ();
    87.     }
    88.  
    89.     IEnumerator RoundsUp()
    90.     {
    91.         startTime = Time.time;
    92.         textElement.text = "00:00";
    93.         updateTime = false;
    94.  
    95.         if (timesUp) {
    96.             GetComponent<AudioSource> ().PlayOneShot (roundsUpSound);
    97.             timesUp = false;
    98.             yield return new WaitForSeconds ((float)freezeTime);
    99.             updateTime = true;
    100.             SpawnManager.spawn.SpawnPlayer ();
    101.             startTime = Time.time;
    102.         }
    103.     }
    104. }
    105.  
     
  2. proandrius

    proandrius

    Unity Technologies

    Joined:
    Dec 4, 2012
    Posts:
    544
    Why so complicated? :)
    Code (csharp):
    1. void Start(){
    2.     StartCoroutine(PlaySoundEvery(1.0f, 3));
    3. }
    4.  
    5. IEnumerator PlaySoundEvery(float t, int times){
    6.     for(int i=0;i<times;i++){
    7.         SpawnManager.spawn.GetComponent<AudioSource>().PlayOneShot(countdownSound [i]);
    8.         yield return new WaitForSeconds(t);
    9.     }
    10.  
    11.     GetComponent<AudioSource>().PlayOneShot(roundsUpSound);
    12. }
    That should be it.
     
    Last edited: Mar 26, 2015
  3. Strategos

    Strategos

    Joined:
    Aug 24, 2012
    Posts:
    255
    I'd just do something simple like Edit: oops got Ninja'd by Proandrius there - not suggesting my method is better than his

    Code (CSharp):
    1.     float timer = 4.0f;
    2.     int countdown = 3;
    3.     public AudioSource[] countdownAudioArray;
    4.  
    5.     void Update()
    6.     {
    7.         timer -= Time.deltaTime;
    8.  
    9.         if (timer > 0.0f)
    10.         {
    11.             if (timer < (float)countdown)
    12.             {
    13.                 countdownAudioArray[countdown].Play();
    14.                 countdown--;
    15.             }
    16.         }
    17.         else
    18.         {
    19.             Debug.Log("Times Up");
    20.         }
    21.     }
     
    proandrius likes this.
  4. Kovenant

    Kovenant

    Joined:
    Sep 18, 2013
    Posts:
    254
    Thanks.. But still the sound clips are playing 58 times in a row...

    This line is called 58 times according to the debugger:
    Code (CSharp):
    1. if (restSeconds == 3) {
    2.             startCount = true;
    3.             StartCoroutine (StartCountdown (1.0f, 3));
    4.         }
    I don't want in the Start function as you suggested... :p
     
  5. proandrius

    proandrius

    Unity Technologies

    Joined:
    Dec 4, 2012
    Posts:
    544
    Probably because restSeconds is equal 3 for 58 frames. You shouldn't do this in Update.
     
  6. Kovenant

    Kovenant

    Joined:
    Sep 18, 2013
    Posts:
    254
    Yeah.. solved it by moving it to this section:
    Code (CSharp):
    1. if (restSeconds == 0) {
    2.             timesUp = true;
    3.             startCount = false;
    4.             StartCoroutine (RoundsUp ());
    5.         } else if (restSeconds == 3 && !startCount) {
    6.             StartCoroutine (StartCountdown (1.0f, 3));
    7.         } else {
    8.             timesUp = false;
    9.         }
    ...and it worked.. thanks everyone for the help.. :)
     
    proandrius likes this.
  7. novashot

    novashot

    Joined:
    Dec 12, 2009
    Posts:
    373
    Code (CSharp):
    1. int timer;
    2.  
    3. void StartCountDown(){
    4.      timer = 3;
    5.      InvokeRepeating("CountDownTick", 1.0f, 1.0f);
    6. }
    7.  
    8. void CountDownTick(){
    9.      //Play Sound Here
    10.      timer--;
    11.  
    12.      if(timer<=0){
    13.           CancelInvoke("CountDownTick");
    14.      }
    15. }