1

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

我将浮动 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();
    }        

}
4

2 回答 2

0

你需要考虑2个因素。

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

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

于 2019-09-28T01:04:34.003 回答
0

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

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

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

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

Coroutine 方法的好处是它通常更易于管理。Update您可以调用一次并让它运行,而不是每次都调用一个方法。由于循环仅限于方法本身,您可以使用DisplayTime将初始值设置countDownTime为 2。

于 2019-09-27T23:58:00.467 回答