【问题标题】:coroutine unity - unpredictable behavior协程统一 - 不可预知的行为
【发布时间】:2020-06-09 11:44:32
【问题描述】:

谁能解释我的代码的问题?

我在程序开始时启动了两个协程。它们是:

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 &lt; loadedObject.Count; foo++)”结束时,加载程序正在工作。

我不明白。我认为,如果full_ 为假,则加载器和缓冲区都必须工作,但只有缓冲区在工作,加载器正在等待“buffer for{} loop”

【问题讨论】:

    标签: unity3d coroutine


    【解决方案1】:

    我不知道你为什么要启动一个协程然后立即停止它。当您调用 StartCoroutine 时,它​​将运行该例程,直到它达到产量。在将例程运行到第一个 yield 后,它将运行启动协程的下一行。

    查看有关事件函数执行顺序的链接: https://docs.unity3d.com/Manual/ExecutionOrder.html#Coroutines

    还有这个关于协程的 https://docs.unity3d.com/Manual/BestPracticeUnderstandingPerformanceInUnity3.html

    所以在你的情况下,事情会按照这个顺序发生:

    1:启动协程

    loader = StartCoroutine(loadobjectsfromfile);
    

    2:运行到第一个yield

     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:运行到第一个yield

     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:跑到第一个yield???不,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
        }
    

    【讨论】:

    • 我只想跳过一些对象,不要将它们添加到我的缓冲区中。在我的第二种情况下,loadedObject.Count = 200 buffer= [50...149](设置为 50)此时 full_ = 1,所以缓冲区和加载器不起作用。由于 displayMesh 协程,一步后 full_ 将为 0。 new buffer=[51...149] 并且 full_ 再次为 1(循环)。好吧,这就是我的问题,当 full_ 为 0 但我的加载器不工作时,缓冲区工作。我的 loaderObjects.Count 仍然是 200。它必须是 201,然后是 202 bla bla。
    猜你喜欢
    • 2012-12-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-03
    • 2014-10-29
    • 2019-06-26
    • 2018-09-03
    相关资源
    最近更新 更多