较新版本的C#有async
/ await
。但在Unity中只有yield
。 如何实现我可以并行yield
的方法?
与Javascript中的Promise.all([])
类似,我们并不关心哪一个首先完成,我们只关心它们何时完成。
为了给出更多上下文,假设你正在设计一个程序化地形生成器,用于生成 in chunks ;并且您已使用ThreadPool
设置要生成的每个块,然后提供返回IEnumerator
的API:
IEnumerator GenerateChunk() {
// procedural generation
// queue itself onto a ThreadPool
// when done, yield
}
IEnumerator GenerateChunks() {
for (int i = 0; i < chunks.Length; i++) {
yield return chunks[i].GenerateChunk();
}
}
void GenerateMap() {
StartCoroutine(GenerateChunks());
}
我们可以做yield IEnumerator[]
吗?
更新:我不确定我是否表达了清楚。基本上我想立即启动所有GenerateChunk
,并允许它们尽快完成,而不是一个接一个地产生。
我的代码是否已经这样做了,还是我还需要其他东西?
答案 0 :(得分:1)
yield return StartCoroutine(chunks[i].GenerateChunk());
答案 1 :(得分:1)
我读了你的问题,阅读了你留下的答案和评论,我相信你不了解协程如何运作。
Coroutine不会并行运行。它将按顺序运行您的代码,同时在同一Thread
。
更新:我不确定我是否表达了清楚。基本上我想立即启动所有GenerateChunk,并允许它们完成 尽可能快,而不是一个接一个地屈服。
我的代码是否已经这样做了,还是我还需要其他东西?
否即可。如果要像位置一样快速调用该函数,则不应在每个函数后yield
。每次yield
,您都在等待一帧。我是否甚至提到你甚至没有正确调用GenerateChunk
功能?仔细看,你也会注意到。 GenerateChunk
函数是一个协程函数,必须使用StartCoroutine()
调用。
在for循环中启动GenerateChunk
后,不会产生效果。你应该只在for循环函数之外产生或破坏。您可以在代码和下面的代码之间进行简单的性能测试,以使用Stopwatch验证这一点。
IEnumerator GenerateChunk()
{
// procedural generation
// queue itself onto a ThreadPool
// when done, yield
}
IEnumerator GenerateChunks()
{
for (int i = 0; i < chunks.Length; i++)
{
StartCoroutine(GenerateChunk());
}
yield break;
//Or yield return null;
}