简体   繁体   中英

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);   
    }

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;
    }
}
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));
        }
    }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM