Unity中立方体高度排序的快速排序协程并行问题及串行化实现需求
解决Unity快速排序协程串行执行的问题
我完全懂你遇到的麻烦——你的可视化快速排序协程在递归处理左右分区时,两个子协程会同时跑起来,直接打乱了你想要一步步串行展示排序过程的预期。问题根源就在最后两行的StartCoroutine调用上:这个方法会立刻启动新协程,不会等待它执行完毕,所以左右分区的排序就并行执行了。
核心解决方案:用yield return等待子协程完成
要实现串行执行,只需要把直接启动协程的代码改成**yield return StartCoroutine(...)**。这样当前协程会暂停,直到子协程完全执行完毕,再继续启动下一个子协程,完美符合你想要的串行逻辑。
另外我注意到你递归时用了全局的cubes数组,而方法参数是unsortedList,这可能会导致逻辑错误,建议统一使用传入的unsortedList参数,保证递归的正确性。
修改后的完整代码
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; // 修改核心:等待左分区排序完成后再执行右分区 yield return StartCoroutine(QuickSort(unsortedList, 0, pivotIndex - 1)); yield return StartCoroutine(QuickSort(unsortedList, pivotIndex + 1, right)); } }
额外优化建议(可选)
如果你希望严格等待LeanTween动画完全结束后再继续排序逻辑(而不是依赖固定的WaitForSeconds),可以利用LeanTween的状态判断来实现更精准的等待:
// 替换原来的WaitForSeconds和LeanTween调用 var tween1 = LeanTween.moveLocalX(unsortedList[i], unsortedList[j].transform.localPosition.x, 1f); var tween2 = LeanTween.moveLocalZ(unsortedList[i], -3f, 0.5f).setLoopPingPong(1); var tween3 = LeanTween.moveLocalX(unsortedList[j], tempPosition.x, 1f); var tween4 = LeanTween.moveLocalZ(unsortedList[j], 3f, 0.5f).setLoopPingPong(1); // 等待所有动画完成后再继续 yield return new WaitUntil(() => tween1.isCompleted && tween2.isCompleted && tween3.isCompleted && tween4.isCompleted);
这样能避免因时间设置不准导致的视觉混乱,让排序动画和逻辑完全同步。
内容的提问来源于stack exchange,提问作者Rafał Gruba
相关产品推荐
相关产品推荐

