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

Unity C#:启动新协程前等待前一个协程完成

Hey there! Let's work through your Unity coroutine problem since you're still getting familiar with how they work.

First, let's break down why your current approaches aren't working:

  1. Parallel coroutine race condition
    When you call StartCoroutine(Coroutine1) and StartCoroutine(Coroutine2) back-to-back, both coroutines run at the same time. That means Coroutine2 might try to access the lists before Coroutine1 finishes generating both—hence the error when only one list exists.

  2. Nested coroutine lockup
    Putting Coroutine2 inside Coroutine1's loop causes a freeze because if Coroutine2 doesn't have any yield return statements to pause and let the main thread breathe, it'll block execution entirely. Even if it does, running it in a tight loop without proper yielding will starve Unity's main loop.

Here are two solid solutions tailored to your goal of avoiding lag while ensuring data is ready:


Solution 1: Wait for both lists to generate before running Coroutine2

This is the simplest fix if you need both lists fully ready before processing. Split your list generation into smaller, yield-friendly chunks to prevent lag, then start Coroutine2 only after both are done:

// Your two lists (make sure they're initialized somewhere!)
private List<YourDataType> list1 = new List<YourDataType>();
private List<YourDataType> list2 = new List<YourDataType>();

void Test()
{
    // Just start the main coordinator coroutine
    StartCoroutine(CoordinateListGenerationAndProcessing());
}

IEnumerator CoordinateListGenerationAndProcessing()
{
    // Generate first list in chunks to avoid lag
    yield return GenerateList(list1, 1000); // Pass list and total items to generate
    // Generate second list similarly
    yield return GenerateList(list2, 1000);
    
    // Now both lists are ready—start processing
    yield return StartCoroutine(Coroutine2());
}

IEnumerator GenerateList(List<YourDataType> targetList, int totalItems)
{
    for (int i = 0; i < totalItems; i++)
    {
        // Add your item generation logic here
        targetList.Add(CreateYourDataItem());
        
        // Yield every 100 items to let Unity process input/rendering
        if (i % 100 == 0)
            yield return null;
    }
}

IEnumerator Coroutine2()
{
    // Process both lists here—also add yields if processing is heavy!
    foreach (var item in list1)
    {
        ProcessItem(item);
        if (list1.IndexOf(item) % 50 == 0)
            yield return null;
    }
    
    foreach (var item in list2)
    {
        ProcessItem(item);
        if (list2.IndexOf(item) % 50 == 0)
            yield return null;
    }
}

Solution 2: Process each list as soon as it's generated

If you don't need both lists ready at the same time, you can start processing the first list immediately after it's done generating, while the second list is still being built. This keeps things running in parallel without blocking:

void Test()
{
    StartCoroutine(CoordinateParallelGenerationAndProcessing());
}

IEnumerator CoordinateParallelGenerationAndProcessing()
{
    // Generate first list, then start processing it right away
    yield return GenerateList(list1, 1000);
    StartCoroutine(Coroutine2(list1)); // Pass the ready list to Coroutine2
    
    // While Coroutine2 is processing list1, generate list2
    yield return GenerateList(list2, 1000);
    StartCoroutine(Coroutine2(list2)); // Process list2 once it's ready
}

// Modified Coroutine2 to accept a single list
IEnumerator Coroutine2(List<YourDataType> listToProcess)
{
    foreach (var item in listToProcess)
    {
        ProcessItem(item);
        if (listToProcess.IndexOf(item) % 50 == 0)
            yield return null;
    }
}

// Reuse the same GenerateList coroutine from Solution 1
IEnumerator GenerateList(List<YourDataType> targetList, int totalItems)
{
    for (int i = 0; i < totalItems; i++)
    {
        targetList.Add(CreateYourDataItem());
        if (i % 100 == 0)
            yield return null;
    }
}

Key takeaways for smooth coroutines:

  • Always split heavy loops with yield return null: This lets Unity handle other tasks (like rendering, input) between chunks of work, preventing freezes.
  • Control execution order: If one coroutine depends on another's output, either wait for the dependent coroutine to finish or pass data incrementally when it's ready.
  • Avoid unyielded loops in coroutines: A coroutine without yields is just a regular function that blocks the main thread—defeats the purpose of using coroutines for lag reduction!

内容的提问来源于stack exchange,提问作者user4676310

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.28 06:57:55