You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.14 06:01:04