greyBow
greyBow

Reputation: 1348

Unity countdown timer jumping to zero and counting down into negatives

Something strange is happening with my countdown timer and I'm stuck. I'm passing a number to my timer (15 seconds) which starts at 15 but then jumps to 0 and then counts down from there: 0, -1, -2, -3... What am I doing incorrectly here?

using UnityEngine;
using UnityEngine.UI;
using System.Collections;

public class CountdownTimer : MonoBehaviour
{
    float seconds;
    public Text timerText;

    public void Update()
    {
        seconds -= Time.deltaTime;
        if (timerText != null)
        {
            timerText.text = Mathf.Round(seconds).ToString();
            Debug.Log (Mathf.Round(seconds));
        }
    }
}

I'm calling the countdown script from a function in another script like this:

void ShowRestartWarning()
    {
        //Debug.Log("Restart Warning Dialog");

        canvas = GameObject.FindGameObjectWithTag("Canvas");

        timerInstance = Instantiate(timeOutWarningDialog);
        timerInstance.transform.SetParent(canvas.transform, false);
        timerInstance.SetActive(true);

        CountdownTimer countdownTimer = timeOutWarningDialog.GetComponent<CountdownTimer>();
        countdownTimer.Update();                                                    

        CancelInvoke();
        Invoke("RestartGame", countdownLength);   
    }

Upvotes: 0

Views: 1076

Answers (2)

mayo
mayo

Reputation: 4075

public class CountdownTimer : MonoBehaviour
{
    float seconds;
    public Text timerText;

    public void Update()
    {
        seconds -= Time.deltaTime;
        if (timerText != null)
        {
            timerText.text = Mathf.Round(seconds).ToString();
            Debug.Log (Mathf.Round(seconds));
        }
    }
}

First the Update() method in a MonoBehaviour that is activated it will be called every frame (More info about that here: Execution Order of Event Functions)

Now, in your script you have 2 variables. First a private seconds and then a public timerText. Why timerText is public? If that variable is not being used by another class should be private.

Now is when you ask; But how I attach a Text component in the editor? Well, you should use SerializeField instead.

Now I think that the error is that you are assigning some value to the Text component. But, your variable seconds is by default zero. (You are declaring a float without any value, by default it will be initialized as 0f).

So the first frame the Text component will display your initial value, let say 15. But the first time that Update() is being called, the line seconds -= Time.deltaTime it will be something like seconds = 0f - Time.deltaTime;, then timerText it will be updated with this new almost zero value.

What can you do? You can use another Event Function, Awake to setup your variable with some value before the Update calls.

If you want to use the value of timerText you can do this:

public class CountdownTimer : MonoBehaviour
{
    private float seconds;

    [SerializeField]
    private Text timerText;

    private void Awake()
    {
        if (!string.isNullOrEmpty(timerText))
        {
            seconds = float.Parse(timerText.text);          
        }
    }

    // Yep, Event Functions can be private and Unity will `call` them anyways
    private void Update() 
    {
        seconds -= Time.deltaTime;
        if (timerText != null)
        {
            timerText.text = Mathf.Round(seconds).ToString();
            Debug.Log (Mathf.Round(seconds));
        }
    }
}

Upvotes: 1

maraaaaaaaa
maraaaaaaaa

Reputation: 8163

Try using a coroutine instead of Update function, that way you can start it and stop it whenever you want.

public Text timerText;

public void Start(int seconds)
{
    StartCoroutine("RunTimer", seconds);
}

IEnumerator RunTimer(int seconds)
{
    while (seconds > 0)
    {
        if (timerText != null)
        {
            timerText.text = seconds.ToString();
            Debug.Log (seconds);
        }
        yield return new WaitForSeconds(1);
        seconds -= 1;
    }
}

Upvotes: 1

Related Questions