统一倒计时器跳到零并倒计数到负片

时间:2017-06-12 12:53:01

标签: c# unity3d timer

我的倒数计时器发生了一些奇怪的事情,我被困住了。我将一个数字传递给我的计时器(15秒),从15开始,然后跳到0然后从那里倒计时:0,-1,-2,-3 ......我在这里做错了什么?< / p>

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

我正在从另一个脚本中的函数调用倒计时脚本,如下所示:

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

2 个答案:

答案 0 :(得分:1)

尝试使用协程而不是更新功能,这样您就可以启动它并随时停止它。

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

答案 1 :(得分: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));
        }
    }
}

首先,MonoBehaviour中的Update()方法会被激活,每个帧都会被调用(此处有关于此的更多信息:Execution Order of Event Functions

现在,在您的脚本中,您有2个变量。首先是私人seconds,然后是公开timerText。 为什么timerText是公开的?如果另一个类没有使用该变量,则应为private

现在是你问的时候;但是我如何在编辑器中附加Text组件?那么,你应该使用SerializeField代替。

现在我认为错误是您正在为Text组件分配一些值。但是,您的变量seconds默认为零。 (您声明一个没有任何值的浮点数,默认情况下它将initialized0f)。

因此Text组件的第一帧将显示您的初始值,比如说15。但是第一次调用Update()时,行seconds -= Time.deltaTime会像seconds = 0f - Time.deltaTime;,然后是timerText,它将使用这个新almost zero进行更新值。

你能做什么?您可以使用其他事件函数AwakeUpdate调用之前使用某个值设置变量。

如果您想使用timerText的值,您可以这样做:

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