【问题标题】:I was wondering why my countdown timer is as I will describe我想知道为什么我的倒数计时器就像我将要描述的那样
【发布时间】:2019-09-28 09:20:44
【问题描述】:

这只是我的代码的一部分,我希望很容易理解。我找到了“修复”它的方法,但我仍然不明白:

我将浮点 countDownTime 设置为 2f。在 DisplayTime() 中,我认为 do-while 循环将从 2 倒数到 0,而是从 0 倒数到负数。我认为当 countDownTime 达到 0 时它会倒计时并停止,正如在 while(countDownTime >= 0) 中分配的那样,但它会继续超出此范围。感谢您提供任何反馈或帮助。

   // Update is called once per frame
void Update()
{
    if (Input.GetKeyDown(KeyCode.Space) && !hasStarted)
    {
        hasStarted = true;
        StartGame();            
    }

    DisplayTime();        
}

void DisplayTime()
{        
    if (timerStart)
    {
        do
        {
            countDownTime -= Time.deltaTime;
        } while (countDownTime >= 0);

        timer2.text = Math.Round(countDownTime, 2).ToString();
    }        

}

我对其进行了更改,这是我的修复:

   // Update is called once per frame
void Update()
{
    if (Input.GetKeyDown(KeyCode.Space) && !hasStarted)
    {
        hasStarted = true;
        StartGame();            
    }

    DisplayTime();        
}

void DisplayTime()
{        
    if (timerStart && countDownTime >= 0)
    {
        do
        {
            countDownTime -= Time.deltaTime;
        } while (countDownTime >= 2);

        timer2.text = Math.Round(countDownTime, 2).ToString();
    }        

}

【问题讨论】:

    标签: unity3d timer do-while countdown


    【解决方案1】:

    首先,我看不到您最初将 countDownTime 设置为 2 的位置。

    其次,countDownTime 更有可能在负数而不是零上停止。这是因为deltaTime 是自上次更新以来经过的毫秒数的度量,并且变化很大。因此,如果您不想显示为负数,则应将其四舍五入。

    最后,我想你想把这段代码作为协程来执行,否则整个循环会在一帧内执行,这很可能不是你想要的。

    IEnumerator DisplayTime() {  
         countDownTime = 2;
         while (countDownTime > 0) {
             countDownTime -= Time.deltaTime;
             timer2.text = Math.Round(countDownTime, 2).ToString();
             yield return new WaitForEndOfFrame();
         }
    }
    
    void Start() {
        // start coroutine
        StartCoroutine(DisplayTime);
    }
    

    如果您不想要协程,并且想从 Update 方法的每一帧调用它,您可以简单地删除 while 循环。

    void DisplayTime() {        
        if (timerStart) {
            if (countDownTime > 0) {
                countDownTime -= Time.deltaTime;
            }
        }
        timer2.text = Math.Round(countDownTime, 2).ToString();
    }
    

    协程方法的好处是它通常更容易管理。与其每次都从Update 调用一个方法,不如调用一次,然后让它运行。由于循环仅限于方法本身,您可以使用DisplayTimecountDownTime 的初始值设置为2。

    【讨论】:

      【解决方案2】:

      您需要考虑两个因素。

      1. Update() 在每一帧上调用方法。您正在从 Update() 调用的 DisplayTime() 中执行 do-while 循环,因此 do while 循环将执行很多次(每帧一次)。
      2. do-while 循环的工作方式与正常的 while 循环不同。 do-while 循环首先执行 do{} 内的代码,并且仅在检查条件后才执行,如果条件为假则中断循环。所以(即使条件为假)do{} 中的代码至少会运行一次。正常情况下while if condition is false,循环内的代码不会运行。

      所以在你的情况下,在第一帧 countDownTime 被订阅,直到它小于 0。(所以在屏幕上你会立即看到 0 而不是 2,因为在第一帧之后它 已经0)。 在执行 do-while 的每一帧的第一帧之后,do 内的代码只执行一次,然后循环立即中断,因为条件 countDownTime >= 已经为假。所以在第一帧之后countDownTime -= Time.deltaTime;这个代码每帧执行一次(在do-while中没有循环多次),这就是它之后“正确”工作的原因。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2019-10-18
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多