簡體   English   中英

什么是 Unity Coroutines,我做錯了什么?

[英]What are Unity Coroutines and what am I doing wrong?

int Partition(GameObject[] list, int left, int right)
{
    GameObject pivot = list[right];

    //GameObject temp;

    int i = left - 1;

    for (int j = left; j <= right - 1; j++)
    {
        if (list[j].transform.position.y <= pivot.transform.position.y)
        {
            i++;
            StartCoroutine(Swap(list, i, j));

        }
    }
    StartCoroutine(Swap(list, i+1, right));
    return i + 1;
}

IEnumerator Swap(GameObject[] list, int i, int j)
{
    temp = list[i];
    list[i] = list[i+1];
    list[i+1] = temp;

    LeanTween.color(list[i], Color.red, 1f);
    LeanTween.color(list[i+1], Color.red, 1f);
    yield return new WaitForSeconds(1.5f);
    LeanTween.color(list[i], Color.white, 1f);
    LeanTween.color(list[i+1], Color.white, 1f);

    tempPosition = list[i].transform.localPosition;

    LeanTween.moveLocalX((list[i]), list[i+1].transform.localPosition.x, 1);

    LeanTween.moveLocalZ(list[i], -3, .5f).setLoopPingPong(1);

    LeanTween.moveLocalX((list[i+1]), tempPosition.x, 1);

    LeanTween.moveLocalZ(list[i+1], 3, .5f).setLoopPingPong(1);
}


void QuickSort(GameObject[] list, int left, int right)
{ 
    int pivot;
    if(left < right)
    {
        pivot = Partition(list, left, right);

        QuickSort(list, left, pivot - 1);

        QuickSort(list, pivot + 1, right);
        
    }

}

我正在嘗試使用協程在每次交換之間添加延遲,因為沒有“Waitforseconds”,所有值都會同時移動,即使通過調試對數組進行排序,它們也會最終出現在錯誤的位置。 我還注意到 StartCoroutine 之后的代碼繼續運行,也許這就是它們最終出現在錯誤位置的原因。 我只是想知道如果有一個 Coroutine 的替代方案,我可以在 LeanTween 循環期間暫停整個事情。 或者我以錯誤的方式使用協程。 提前致謝。

這里的問題是您在同一幀上開始所有交換,而不是按順序進行。 這是因為您多次調用StartCoroutine而沒有從 Update 中返回(或者在協程的情況下返回 yield)。

您應該讓Partition成為協程,然后在每次調用Swap時讓出,以便等待每個Swap協程完成后再繼續。 另外,請在每次交換結束時等待。

由於協程的返回值是為管理控制流而保留的,因此您可以向協程發送委托以調用結果。 為此使用Action<int>

共:

IEnumerator Partition(GameObject[] list, int left, int right, Action<int> onComplete)
{
    GameObject pivot = list[right];

    //GameObject temp;

    int i = left - 1;

    for (int j = left; j <= right - 1; j++)
    {
        if (list[j].transform.position.y <= pivot.transform.position.y)
        {
            i++;
            yield return Swap(list, i, j);

        }
    }
    yield return Swap(list, i+1, right);
    onComplete.Invoke(i + 1);
}

IEnumerator Swap(GameObject[] list, int i, int j)
{
    temp = list[i];
    list[i] = list[i+1];
    list[i+1] = temp;

    LeanTween.color(list[i], Color.red, 1f);
    LeanTween.color(list[i+1], Color.red, 1f);
    yield return new WaitForSeconds(1.5f);
    LeanTween.color(list[i], Color.white, 1f);
    LeanTween.color(list[i+1], Color.white, 1f);

    tempPosition = list[i].transform.localPosition;

    LeanTween.moveLocalX((list[i]), list[i+1].transform.localPosition.x, 1);

    LeanTween.moveLocalZ(list[i], -3, .5f).setLoopPingPong(1);

    LeanTween.moveLocalX((list[i+1]), tempPosition.x, 1);

    LeanTween.moveLocalZ(list[i+1], 3, .5f).setLoopPingPong(1);
    yield return new WaitForSeconds(1.5f);
}



void QuickSort(GameObject[] list, int left, int right)
{ 
    if(left < right)
    {
        Action<int> callback = pivot =>
        {
            QuickSort(list, left, pivot - 1);
            QuickSort(list, pivot + 1, right);
        };

        StartCoroutine(Partition(list, left, right, callback));  
    }
}

如果您希望相鄰的QuickSort調用按順序發生而不是同時發生,那么問題會變得有點棘手,因為您需要能夠在它們之間產生 return!

因此,要使用協程實現這一點,您還需要在協程中進行QuickSortcallback 您不能在匿名函數中使用 yield 返回,因此 callback 需要改為接受它使用的每個變量的參數的方法,然后Partition需要相應地提供它們:

IEnumerator Partition(GameObject[] list, int left, int right)
{
    GameObject pivot = list[right];

    //GameObject temp;

    int i = left - 1;

    for (int j = left; j <= right - 1; j++)
    {
        if (list[j].transform.position.y <= pivot.transform.position.y)
        {
            i++;
            yield return Swap(list, i, j);

        }
    }
    yield return Swap(list, i+1, right);
    yield return QuickSortCallback(list, left, right, i + 1);
}

IEnumerator QuickSortCallback(GameObject[] list, int left, int right, int pivot)
{
    yield return QuickSort(list, left, pivot - 1);
    yield return QuickSort(list, pivot + 1, right);
}

IEnumerator QuickSort(GameObject[] list, int left, int right)
{ 
    if(left < right)
    {
        yield return Partition(list, left, right));  
    }
}

/* unchanged from above, just including here for convenience */
IEnumerator Swap(GameObject[] list, int i, int j)
{
    temp = list[i];
    list[i] = list[i+1];
    list[i+1] = temp;

    LeanTween.color(list[i], Color.red, 1f);
    LeanTween.color(list[i+1], Color.red, 1f);
    yield return new WaitForSeconds(1.5f);
    LeanTween.color(list[i], Color.white, 1f);
    LeanTween.color(list[i+1], Color.white, 1f);

    tempPosition = list[i].transform.localPosition;

    LeanTween.moveLocalX((list[i]), list[i+1].transform.localPosition.x, 1);

    LeanTween.moveLocalZ(list[i], -3, .5f).setLoopPingPong(1);

    LeanTween.moveLocalX((list[i+1]), tempPosition.x, 1);

    LeanTween.moveLocalZ(list[i+1], 3, .5f).setLoopPingPong(1);
    yield return new WaitForSeconds(1.5f);
}

瀏覽此處獲取更多信息

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM