gpt4 book ai didi

c# - unity StopCoroutine 存在多层(或嵌套)时不停止协程 "yield return"

转载 作者:行者123 更新时间:2023-11-30 12:20:29 25 4
gpt4 key购买 nike

如果我使用一层 yield returnStopCoroutine() 可以成功停止我的协程。请参阅下面的代码示例...

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class TestStopcoroutine : MonoBehaviour {
IEnumerator co = null;

// Use this for initialization
void Start () {
co = FunA();
StartCoroutine(co);
}

private IEnumerator FunA() {
Debug.Log("Enter FunA...");
yield return RepeatPrint();
Debug.Log("FunA end...");
}

private IEnumerator RepeatPrint() {
for (int i = 0; i < 5; i++) {
Debug.Log(i);
yield return new WaitForSeconds(1);
}
}

/// <summary>
/// Set this function to a button on UI Canvas
/// </summary>
public void OnCancelButtonClick() {
if (co != null) {
StopCoroutine(co);
Debug.Log("Stop Coroutine...");
co = null;
}
}
}

这个输出是...

// Enter FunA...
// 0
// 1
// 2
// 3
// Stop Coroutine...

但是,如果我添加一层(即 FunB()),FunA() 将停止,但内部协程(FunB()) 不会停止。请参阅下面的示例代码:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class TestStopcoroutine : MonoBehaviour {
IEnumerator co = null;

void Start () {
co = FunA();
StartCoroutine(co);
}

private IEnumerator FunA() {
Debug.Log("Enter FunA...");
yield return FunB();
Debug.Log("FunA end...");
}

private IEnumerator FunB () {
Debug.Log("Enter FunB...");
yield return RepeatPrint();
Debug.Log("FunB end...");
}

private IEnumerator RepeatPrint() {
for (int i = 0; i < 5; i++) {
Debug.Log(i);
yield return new WaitForSeconds(1);
}
}

/// <summary>
/// Set this function to a button on UI Canvas
/// </summary>
public void OnCancelButtonClick() {
if (co != null) {
StopCoroutine(co);
Debug.Log("Stop Coroutine...");
co = null;
}
}
}

这个输出是...

// Enter FunA...
// Enter FunB...
// 0
// 1
// 2
// Stop Coroutine...
// 3
// 4
// FunB end...

因此,我想知道为什么StopCoroutine()不能成功停止多层yield return协程??

最佳答案

对于您的第二个代码,日志确实应该以 Stop Coroutine.... 结尾。

显示当前输出的原因有以下三种可能性:(很可能是为了说明为什么会这样)

1。您正在将 Time.timeScale 设置为 0。在您的整个项目中搜索并确保您没有这样做:Time.timeScale = 0;。这可以暂停或暂停正在等待 WaitForSeconds 的协程函数。如果是,请暂时将其删除或将其注释掉,看看是否是问题所在。

2。您的项目已损坏,现在有一个错误。有时,Unity 项目中可能会随机发生错误,修复该错误的唯一方法是创建一个新项目并手动将资源从旧项目移动到新项目。

创建一个新项目并在下面测试您修改后的代码。

3。 Unity 本身的错误。由于您使用的是 Unity 5.6.4p3,这很可能是 Unity 的错误。如果执行#1#2 中的操作未能解决您的问题,则只需将 Unity 更新到最新版本 (Unity 2018.xxx)。这更有可能解决您的问题,并且不要忘记使用新项目进行测试而不是导入旧项目。

使用下面问题中修改后的代码来测试 #2#3。它使用 Invoke 函数在 1 秒后停止协程。

IEnumerator co = null;

void Start()
{
co = FunA();
Invoke("OnCancelButtonClick", 1f);
StartCoroutine(co);
}

private IEnumerator FunA()
{
Debug.Log("Enter FunA...");
yield return FunB();
Debug.Log("FunA end...");
}

private IEnumerator FunB()
{
Debug.Log("Enter FunB...");
yield return RepeatPrint();
Debug.Log("FunB end...");
}

private IEnumerator RepeatPrint()
{
for (int i = 0; i < 5; i++)
{
Debug.Log(i);
yield return new WaitForSeconds(1);
}
}

/// <summary>
/// Set this function to a button on UI Canvas
/// </summary>
public void OnCancelButtonClick()
{
if (co != null)
{
StopCoroutine(co);
Debug.Log("Stop Coroutine...");
co = null;
}
}

预期输出:

Enter FunA...

Enter FunB...

0

Stop Coroutine...

地址KYL3R's他在回答中声明停止主协程不会影响任何其他已经启动的协程。这部分正确,但完全取决于协同程序的启动方式和位置。

启动协程函数有两种方式:

1。从任何函数(例如具有 void 返回类型的函数)中使用 StartCoroutine 函数启动协程。

void Start()
{
StartCoroutine(RepeatPrint());
}

IEnumerator Start()
{
yield return StartCoroutine(RepeatPrint());
}

2。通过生成要启动的协程函数来启动协程函数而不 StartCoroutine 函数。这必须在协程函数或具有 IEnumerator 返回类型的函数内完成。它不能在像 void 函数这样的普通函数中完成。

IEnumerator Start()
{
yield return RepeatPrint();
}

当您使用 StartCoroutine 启动协程,然后使用 StartCoroutine 启动子协程,然后终止父协程时,子协程函数将并且应该继续 不受影响地运行。

现在,当您使用 StartCoroutine 启动协程,然后在 yield return YourCoroutine() 使用 之后启动子协程StartCoroutine 函数但随后终止了父协程,子协程函数将并且应该像父协程一样立即终止或停止

大多数 Unity 用户不知道这并不奇怪,因为它没有记录,但在 Unity 中使用协程时了解这一点非常重要。

关于c# - unity StopCoroutine 存在多层(或嵌套)时不停止协程 "yield return",我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51550499/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com