C# Unity倒计时计时器跳到零并倒计时到负数

C# Unity倒计时计时器跳到零并倒计时到负数,c#,unity3d,timer,C#,Unity3d,Timer,我的倒计时计时器有点奇怪,我卡住了。我将一个数字传递给我的计时器(15秒),计时器从15开始,然后跳到0,然后从那里开始倒计时:0,-1,-2,-3。。。我在这里做错了什么 using UnityEngine; using UnityEngine.UI; using System.Collections; public class CountdownTimer : MonoBehaviour { float seconds; public Text timerText;

我的倒计时计时器有点奇怪,我卡住了。我将一个数字传递给我的计时器(15秒),计时器从15开始,然后跳到0,然后从那里开始倒计时:0,-1,-2,-3。。。我在这里做错了什么

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);   
    }
void showrestwarning()
{
//Log(“重新启动警告对话框”);
canvas=GameObject.FindGameObjectWithTag(“canvas”);
timerInstance=实例化(timeOutWarningDialog);
timerInstance.transform.SetParent(canvas.transform,false);
timerInstance.SetActive(真);
CountdownTimer CountdownTimer=timeOutWarningDialog.GetComponent();
countdownTimer.Update();
取消调用();
调用(“重启游戏”,倒计时长度);
}

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

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 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;
    }
}
首先,MonoBehavior中的
Update()
方法被激活,它将在每一帧调用一次(更多信息如下:)

现在,在脚本中有两个变量。首先是私有的
,然后是公共的
定时器文本
。 为什么
timerText
是公共的?如果该变量未被其他类使用,则该变量应为
private

现在是你问的时候;但是如何在编辑器中附加
文本
组件?嗯,你应该改用

现在我认为错误在于您正在为文本组件分配一些值。但是,您的变量
seconds
默认为零。(您声明的浮点值没有任何值,默认情况下,它将被初始化为)

因此,文本组件的第一帧将显示初始值,比如说
15
。但是第一次调用
Update()
时,行
seconds-=time.deltaTime
类似于
seconds=0f-time.deltaTime
,然后它将用这个新的
几乎为零的
值更新

你能做什么?您可以使用另一个事件函数,在调用
Update
之前使用一些值设置变量

如果要使用
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));
        }
    }
}
首先,MonoBehavior中的
Update()
方法被激活,它将在每一帧调用一次(更多信息如下:)

现在,在脚本中有两个变量。首先是私有的
,然后是公共的
定时器文本
。 为什么
timerText
是公共的?如果该变量未被其他类使用,则该变量应为
private

现在是你问的时候;但是如何在编辑器中附加
文本
组件?嗯,你应该改用

现在我认为错误在于您正在为文本组件分配一些值。但是,您的变量
seconds
默认为零。(您声明的浮点值没有任何值,默认情况下,它将被初始化为)

因此,文本组件的第一帧将显示初始值,比如说
15
。但是第一次调用
Update()
时,行
seconds-=time.deltaTime
类似于
seconds=0f-time.deltaTime
,然后它将用这个新的
几乎为零的
值更新

你能做什么?您可以使用另一个事件函数,在调用
Update
之前使用一些值设置变量

如果要使用
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));
        }
    }
}

如何启动计时器?(如何调用
startTimer
?)
Update()
由MonoBehavior自动运行。我想你自己运行它可能会有一些奇怪的行为。第一次运行时,
Time.deltaTime
的值是多少?如果基类运行
Update()
,它不应该在
CountdownTimer
中有重写吗?@Maakep我正在从另一个脚本调用Update来触发倒计时。这不是方法吗?@MarkusDeibel Time.deltaTime的值从零开始,即使我将秒设置为15。如何启动计时器?(如何调用
startTimer
?)
Update()
由MonoBehavior自动运行。我想你自己运行它可能会有一些奇怪的行为。第一次运行时,
Time.deltaTime
的值是多少?如果基类运行
Update()
,它不应该在
CountdownTimer
中有重写吗?@Maakep我正在从另一个脚本调用Update来触发倒计时。这不是方法吗?@MarkusDeibel Time.deltaTime的值从零开始,即使我将秒设置为15。