超时后结束协程函数内循环的最佳方法是什么?

What's the best way to end a loop inside a coroutine function after time?

这是我的第一个问题,我想一切都清楚了 -

协程 (UnityC#) 中的循环运行不正确,或者我做错了什么!检查代码注释...

bool loop=true;
bool once=false;   

IEnumerator Fun()
{
    while (loop)
    {
        //those 3 lines must be repeated for the whole 2.5 seconds,am I right! but it only run once so why?
        carRb.drag += .005f;
        Debug.Log("Loop1:"+loop);
        if (!once)          //last rep. line
        { 
            once = true;
            yield return new WaitForSeconds(2.5f); 
            loop = false;
        }
        yield return new WaitForEndOfFrame();
    }
    yield return new WaitForSeconds(2f); //will run this line after 2.5s        
    Debug.Log("Loop2: "+loop);      //will run this line and whats below after (2.5+2s) 
    carRb.drag = 25f;
    carController.canControl = false;
    Destroyed = true; 
}

once的值为false,进入if条件等待2.5s结束循环

bool loop=true;
bool once=false;

IEnumerator Fun()
{
    float time=0;
    while (loop)
    {
        //those 3 lines must be repeated for the whole 2.5 seconds,am I right! but it only run once so why?
        carRb.drag += .005f;
        Debug.Log("Loop1:"+loop);
        yield return null;  // wait each update call
        time+=Time.deltaTime;
        if (time>2.5f)          //last rep. line
        {
            once = true;
            loop = false;
        }
    }
    yield return new WaitForSeconds(2f); //will run this line after 2.5s
    Debug.Log("Loop2: "+loop);      //will run this line and whats below after (2.5+2s)
    carRb.drag = 25f;
    carController.canControl = false;
    Destroyed = true;
}

解释此处误解的最清楚的方法是:

  1. WaitForSeconds 在单独的盒子或类似的东西中不起作用 所以

  2. 它会阻止整个代码继续,直到时间结束,这意味着即使我们在关闭循环之前等待(设置 loop=false),我们仍将处于第一次迭代中。 结束循环的最好方法是使用一个数值变量,每帧增加它并检查它是否达到我们想要的时间然后 break

感谢@user3315036 和@Absinthe

Code will be like:

IEnumerator Fun(){
    float time=0;

    while(time<2.5f){
        carRb.drag += .005f;
        Debug.Log("Loop1");
        time+=Time.deltaTime;       
        yield return null;

    }
    yield return new WaitForSeconds(2f); //will run this line after 2.5s        
    Debug.Log("2: ");      //will run this line and whats below after (2.5+2s) 
    carRb.drag = 25f;
    carController.canControl = false;
    Destroyed = true; 

}