我将在另一个协程中等待几个协程。示例代码
private IEnumerator WaitForAllAnimations(List<ShiftedGem> shiftedGems)
{
float duration = 3f;
isDuringAnimation = true;
List<Coroutine> animationCoroutines = new List<Coroutine>();
for (int i = 0; i < shiftedGems.Count(); i++)
{
ShiftedGem shiftedGem = shiftedGems[i];
Debug.Log("Add animation");
ShiftAnimation shiftAnimation = shiftedGem.GameObject.AddComponent<ShiftAnimation>();
yield return StartCoroutine(shiftAnimation.AnimateShift(shiftedGem.GameObject, shiftedGem.ShiftAmount, duration));
animationCoroutines.Add(animationCoroutine);
}
foreach (Coroutine coroutine in animationCoroutines)
{
Debug.Log("Wait for coroutine");
yield return coroutine;
}
Debug.Log("Animation end");
isDuringAnimation = false;
}
但是,它并不像预期的那样工作-在AnimateShift完成之前调用Debug.log(“Animationend”)。
我尝试了一个更简单的例子:
IEnumerator CoroutineA(List<ShiftedGem> shiftedGems)
{
Debug.Log("Start Coroutine A");
yield return StartCoroutine(CoroutineB());
Debug.Log("End Coroutine A");
}
IEnumerator CoroutineB()
{
Debug.Log("Start Coroutine B");
yield return new WaitForSeconds(1f);
Debug.Log("End Coroutine B");
}
这工作正常(“End Coroutine A”记录在“End Coroutine B”之后)。
但是如果我将StartCoroutine(CoroutineB())移动到循环中:
IEnumerator CoroutineA(List<ShiftedGem> shiftedGems)
{
Debug.Log("Start Coroutine A");
foreach (ShiftedGem shiftedGem in shiftedGems)
{
yield return StartCoroutine(CoroutineB());
}
Debug.Log("End Coroutine A");
}
IEnumerator CoroutineB()
{
Debug.Log("Start Coroutine B");
yield return new WaitForSeconds(10f);
Debug.Log("End Coroutine B");
}
然后再次-Debug.log(“End Coroutine A”)在Debug.log(“End Coroutine B”)之前调用。
我应该如何组织我的代码,以便能够等待WaitForAllAnimations协程中的所有animationCoroutines?
2条答案
按热度按时间fd3cxomn1#
首先,你在协程列表中添加一个对象,我没有看到它被分配到任何地方,这看起来有点奇怪。无论如何,关于选项:
您可以使用某种计数器来计算当前运行的协程数量。基于您的最后一段代码:
但是,请注意,如果第二次运行以上代码,直到上一次调用尚未完成,则上述代码将不稳定。
我认为对现有变体进行最少更改的最佳选择是在
ShiftAnimation
组件中添加一个标志,以检查动画是否仍在进行中。在
ShiftAnimation
组件中,类似于这样的内容:kx5bkwkv2#
如果你正在寻找一种更好的方式来处理Unity中的异步任务,我建议你看看UniTask plugin。这个插件提供了一个易于使用的替代传统的C# async/await,以及Unity的协程,这可能很难使用。
使用UniTask,您可以使用
WhenAll()
方法来等待多个任务完成。这种方法只需要将现有的协程重构为异步方法,这可以简化代码并提高其可读性。