unity3d - 协程统一 - 不可预知的行为
问题描述
任何人都可以解释我的代码的问题吗?
我在程序开始时启动了两个协程。这些是:
loader = StartCoroutine(loadobjectsfromfile);
buffer = StartCoroutine(setBufferToSpesificLocation(0));
简要说明 loadobjectsfromfile 从文件中读取 obj 并将它们添加到List<GameObjects> loadedObject
. Ant 它读取更多,直到缓冲区已满。
IEnumerator loadobjectsfromfile(string filepath, List<GameObject> objs)
{ while(...)
{
// other code lines
// ...
loadedObject.Add(gam);
while (full_)
{
yield return null;
}
k++;
yield return null;
} }
setBufferTheSpesificLocation 将列表中的对象添加到 buffer[] 数组。它还会放置对象,直到缓冲区已满。
IEnumerator setBufferToSpesificLocation(int startPoint)
{
for ( foo = startPoint; foo < loadedObject.Count; foo++)
{
while (full_)
{
yield return null;
}
put(loadedObject[foo]);
yield return null;
}
}
void put(GameObject frame)
{
buff_[head_] = frame;
head_ = (head_ + 1) % bufferSize;
full_ = head_ == tail_;
}
最后一部分,我们如何清空缓冲区?我调用 display 调用的其他协程。
IEnumerator displayMesh(GameObject[] objs)
{
while (!empty())
{
// other lines
full_ = false; // have a free space
}
}
好吧,如果我启动前两个协程,然后调用最后一个协程(没有问题。我的代码运行良好。但是我遇到了一个新案例的问题。
loader = StartCoroutine(loadobjectsfromfile);
buffer = StartCoroutine(setBufferToSpesificLocation(0));
StopCoroutine(buffer);
buffer = StartCoroutine(setBufferToSpesificLocation(50)); //
play = StartCoroutine(displayMesh(buff_));
问题是,在调用第二个缓冲区协程后,加载程序在这种情况下不起作用。当“ ( foo = startPoint; foo < loadedObject.Count; foo++)
”结束时,加载程序正在工作。
我不明白。我认为,如果full_
为假,加载器和缓冲区都必须工作,但只有缓冲区在工作,加载器正在等待“缓冲区 for{} 循环”
解决方案
我不知道你为什么要启动一个协程然后立即停止它。当您调用 StartCoroutine 时,它将运行该例程,直到它达到产量。在将例程运行到第一个 yield 后,它将运行启动协程的下一行。
检查有关事件函数执行顺序的链接: https ://docs.unity3d.com/Manual/ExecutionOrder.html#Coroutines
这一篇关于协程 https://docs.unity3d.com/Manual/BestPracticeUnderstandingPerformanceInUnity3.html
因此,在您的情况下,事情将按以下顺序发生:
1:启动协程
loader = StartCoroutine(loadobjectsfromfile);
2:运行到第一个产量
IEnumerator loadobjectsfromfile(string filepath, List<GameObject> objs)
{ while(...)
{
// other code lines
// ...
loadedObject.Add(gam);
while (full_)
{
yield return null;
}
k++;
yield return null; //<<<<<<<<<<<<<<HERE<<<<<<<<<<<<<<<<<<<<
} }
3:启动下一个协程
buffer = StartCoroutine(setBufferToSpesificLocation(0));
4:运行到第一个产量
IEnumerator setBufferToSpesificLocation(int startPoint)
{
for ( foo = startPoint; foo < loadedObject.Count; foo++)
{
while (full_)
{
yield return null;
}
put(loadedObject[foo]);
yield return null; //<<<<<<<<<<<<<<HERE<<<<<<<<<<<<<<<<<<<<
}
}
4:停止缓冲程序
StopCoroutine(buffer);
5:再次启动缓冲区,但现在 startPoint 参数设置为 50
buffer = StartCoroutine(setBufferToSpesificLocation(50));
6:跑到第一个产量???不,foo = startPoint 现在是 50...
IEnumerator setBufferToSpesificLocation(int startPoint)
{
//it will skip the loop as foo is 50 and loadedObject.Count is 1 (probabbly)
for ( foo = startPoint; foo < loadedObject.Count; foo++)
{
//code...
}
//WILL END THE COROUTINE
}