一段时间后结束协程函数内循环的最佳方法是啥?
Posted
技术标签:
【中文标题】一段时间后结束协程函数内循环的最佳方法是啥?【英文标题】:What's the best way to end a loop inside a coroutine function after time?一段时间后结束协程函数内循环的最佳方法是什么? 【发布时间】:2021-10-15 18:49:37 【问题描述】:这是我的第一个问题,我猜一切都很清楚-
协程 (UnityC#) 中的循环行为不正确,或者我做错了什么!检查代码 cmets...
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;
【问题讨论】:
如果你没有告诉我们你想做什么,我们怎么能告诉你你做错了什么? 请提供minimal reproducible example 清楚地表明您遇到的问题 我试图在 2.5 秒后结束 courotine 中的循环,它仅在 1 帧后结束 欢迎来到 SO。请原谅这里的巨魔,最近似乎有一种文化,即向那些提出合理问题但没有 100% 遵守规则的人发起攻击。要在特定时间后结束循环,您只需要在循环内添加一个计时器变量并添加 2.5 秒。当它达到您的阈值时,循环应该退出。将While (loop)
更改为While (myTimer < 30)
或您选择的任何时间。上面的评论是对的,问题的格式是:***.com/help/minimal-reproducible-example
谢谢@Absinthe
【参考方案1】:
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 帧)并且 Log 函数只打印一次 你没有提供任何新东西,还是谢谢你 您将在第一次迭代中关闭循环,因此它不会循环多次。等待几秒钟使代码等待 2.5 秒。在此之前它不会执行下一行代码 yield return new WaitForSeconds(2.5f);代码只是坐在那里,什么也不做。在 2.5 之后 sencode loop = false;行执行。所以在下一次迭代中while循环退出 以及它之后的下一行是 loop=false;正在发生,......你说它什么都不做,但它不会阻止它执行后发生的事情,你能解释一下吗?谢谢【参考方案2】:最清晰的方式解释这里的误解是:
WaitForSeconds 不能在单独的盒子或类似的东西中工作 所以
它会阻止整个代码继续运行,直到时间结束,这意味着即使我们在关闭循环之前等待(设置 loop=false),我们仍将处于第一次迭代中。 结束循环的最好方法是使用数值变量,每帧增加它并检查它是否达到我们想要的时间然后中断
感谢@user3315036 和@Absinthe
代码如下:
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;
【讨论】:
当有人能够在 cmets 中回答您的问题时,通常会要求他们添加答案并接受。 他们的答案不是第一个好的答案,这就是答案:(一次的值为假,所以它进入 if 条件然后等待 2.5 秒并结束循环),他们在讨论后对其进行了编辑,即使在我们不清楚的编辑之后,我也会在 BIG BOLD Title 中提到他们的名字以上是关于一段时间后结束协程函数内循环的最佳方法是啥?的主要内容,如果未能解决你的问题,请参考以下文章
Laravel 3 - 查询同一天的开始和结束日期的最佳方法是啥
现在 MPMoviePlayerPlaybackDidFinishReasonUserInfoKey 已被弃用,找到播放结束原因的最佳方法是啥?