Search code examples
c#unity-game-enginequicksort

Unity - C# - quick sort alghoritm - courutines


I am writing an app in Unity that will sort cubes by it's height. I'm stuck with Quick sort alghoritm.

Code is working correctly until the last 2 lines which are courutines instead of regular methods. Unfortunately they both run in paralel which is wrong... I'm looking for a way to build my code to run only one courutine at the time.

IEnumerator QuickSort(GameObject[] unsortedList, int left, int right)
{
    if (left < right)
    {
        GameObject temp;
        Vector3 tempPosition;
        float pivotValue = unsortedList[right].transform.localScale.y;
        int i = left - 1;

        for (int j = left; j < right; j++)
        {
            if (unsortedList[j].transform.localScale.y < pivotValue)
            {
                i++;

                temp = unsortedList[i];
                unsortedList[i] = unsortedList[j];
                unsortedList[j] = temp;
                if (i != j)
                {
                    yield return new WaitForSeconds(1);

                    tempPosition = unsortedList[i].transform.localPosition;

                    LeanTween.moveLocalX(unsortedList[i], unsortedList[j].transform.localPosition.x, 1f);
                    LeanTween.moveLocalZ(unsortedList[i], -3f, 0.5f).setLoopPingPong(1);

                    LeanTween.moveLocalX(unsortedList[j], tempPosition.x, 1f);
                    LeanTween.moveLocalZ(unsortedList[j], 3f, 0.5f).setLoopPingPong(1);
                }
            }
        }
        yield return new WaitForSeconds(1);

        temp = unsortedList[i + 1];
        unsortedList[i + 1] = unsortedList[right];
        unsortedList[right] = temp;

        tempPosition = unsortedList[i + 1].transform.localPosition;

        LeanTween.moveLocalX(unsortedList[i + 1], unsortedList[right].transform.localPosition.x, 1f);
        LeanTween.moveLocalZ(unsortedList[i + 1], -3f, 0.5f).setLoopPingPong(1);

        LeanTween.moveLocalX(unsortedList[right], tempPosition.x, 1f);
        LeanTween.moveLocalZ(unsortedList[right], 3f, 0.5f).setLoopPingPong(1);

        int pivotIndex = i + 1;

        StartCoroutine(QuickSort(cubes, 0, pivotIndex - 1));
        StartCoroutine(QuickSort(cubes, pivotIndex + 1, cubes.Length - 1));
    }
}

Solution

  • If you are just using StartCoroutine you are running the subsequent Coroutines as new parallel routines.

    If you want to actually wait until these recursive routines are finished before running the next one then you have to yield them like e.g.

    // This already "runs" this IEnumerator and at the same time waits until it is done
    yield return QuickSort(cubes, 0, pivotIndex - 1);
    yield return QuickSort(cubes, pivotIndex + 1, cubes.Length - 1);
    

    you also don't need the StartCoroutine then at all. This would only be required if you would want to be able to use StopCoroutine on the individual started routines.

    Honestly personally I wouldn't mix too much between LeanTween and coroutines, though ;)