Unity中如何在协程遇Exception或失败时终止?跳过后续代码
Unity协程终止问题:CoTest_B失败时停止执行CoTest_C
下面提供几种简洁的解决方案,避免用杂乱的布尔变量实现:
方案1:通过异常捕获终止协程链
在CoTest_B触发失败或抛出异常时,主动抛出自定义异常,主协程捕获后直接终止,跳过后续逻辑:
// 自定义异常用于标记协程失败 public class CoroutineFailureException : Exception { } IEnumerator CoTest_B(Action onSuccess, Action onFail) { try { // 替换为CoTest_B的实际业务逻辑 bool operationSucceeded = false; if (operationSucceeded) { onSuccess?.Invoke(); } else { onFail?.Invoke(); // 抛出异常终止后续协程 throw new CoroutineFailureException(); } yield return null; // 示例等待步骤,替换为实际代码 } catch (Exception) { onFail?.Invoke(); throw new CoroutineFailureException(); } } IEnumerator CoTest_Main() { yield return CoTest_A(); try { yield return CoTest_B(() => Debug.Log("CoTest_B执行成功"), () => Debug.Log("CoTest_B执行失败")); // 仅当CoTest_B正常完成时才执行CoTest_C yield return CoTest_C(); } catch (CoroutineFailureException) { // 捕获失败信号,直接终止协程 yield break; } }
方案2:通过输出参数传递执行状态
用out参数在CoTest_B执行完成后返回成功状态,主协程根据状态决定是否继续:
IEnumerator CoTest_B(Action onSuccess, Action onFail, out bool isSuccess) { isSuccess = false; try { // 替换为实际业务逻辑 bool operationSucceeded = false; if (operationSucceeded) { onSuccess?.Invoke(); isSuccess = true; } else { onFail?.Invoke(); } yield return null; } catch (Exception) { onFail?.Invoke(); isSuccess = false; } } IEnumerator CoTest_Main() { yield return CoTest_A(); bool bExecutedSuccessfully = false; yield return CoTest_B(() => Debug.Log("CoTest_B成功"), () => Debug.Log("CoTest_B失败"), out bExecutedSuccessfully); if (bExecutedSuccessfully) { yield return CoTest_C(); } // 状态为失败时直接结束,不执行CoTest_C }
方案3:通用协程结果包装器(复用性更强)
封装一个结果类,统一处理协程的成功/失败状态,避免重复代码:
public class CoroutineResult { public bool IsSuccess { get; private set; } public Exception Error { get; private set; } public void SetSuccess() => IsSuccess = true; public void SetFailed(Exception error = null) { IsSuccess = false; Error = error; } } IEnumerator CoTest_B(Action onSuccess, Action onFail, CoroutineResult result) { try { // 实际业务逻辑 bool operationSucceeded = false; if (operationSucceeded) { onSuccess?.Invoke(); result.SetSuccess(); } else { onFail?.Invoke(); result.SetFailed(); } yield return null; } catch (Exception ex) { onFail?.Invoke(); result.SetFailed(ex); } } IEnumerator CoTest_Main() { yield return CoTest_A(); var bResult = new CoroutineResult(); yield return CoTest_B(() => Debug.Log("CoTest_B成功"), () => Debug.Log("CoTest_B失败"), bResult); if (bResult.IsSuccess) { yield return CoTest_C(); } }
内容的提问来源于stack exchange,提问作者Dddg Hgh
相关产品推荐
相关产品推荐

