在协同程序运行时,应用程序/游戏完全冻结

时间:2018-04-28 15:59:01

标签: unity3d arcore

我的Android ARCore Unity应用程序/游戏在协程运行时冻结,然后在协程完成后恢复。协程附加到游戏对象的脚本中,协程在Start()函数中调用。我已经尝试将yield return null;插入协程的更多部分,这减少了暂停的时间,但增加了更多的暂停,导致在实例化对象后一两秒内非常不稳定(基本上不存在)游戏玩法。可能会发生这种情况,因为ARCore不支持多线程渲染吗?如果是这种情况(或不是)我该如何解决这个问题,那么在对象实例化之后我的协同程序会运行(我猜在后台'),所以它不会影响游戏性FPS?

这是我的代码:

void Start() 
{
    StartCoroutine(MyCoroutine());
}

IEnumerator MyCoroutine ()
{
    yield return null;
    Transform[] allChildren = GetComponentsInChildren<Transform>();
    foreach (Transform child in allChildren)
    {
        if (child.gameObject.GetComponent<MeshFilter>())
        {
            if (!child.gameObject.GetComponent<MeshCollider>())
            {
                child.gameObject.AddComponent<MeshCollider>();
            }
        }
        child.gameObject.tag = "CenterObject";
    }
}

3 个答案:

答案 0 :(得分:4)

Coroutines在构建它们时似乎有一些开销,如下所述:https://forum.unity.com/threads/startcoroutine-performance-cost.233623/

鉴于您正在实例化对象,我建议这些路径:

  • 将协同程序更改为一个简单的函数调用,因为您似乎不需要在循环的迭代之间进行任何延迟,这是在Unity中使用协程的主要思想。您还要添加碰撞器并期望继续玩游戏,如果您需要注册碰撞,这可能会导致意外行为。
  • 如果可能,实例化预先附有碰撞器的预制件。
  • 使用对象池,您可以在游戏开始之前创建对象,并在需要时激活它们,并在必要时禁用它们。

答案 1 :(得分:2)

这是因为你在协程中陷入了循环。您需要将yield移动到循环内部:

IEnumerator MyCoroutine ()
{
    Transform[] allChildren = GetComponentsInChildren<Transform>();
    foreach (Transform child in allChildren)
    {
        if (child.gameObject.GetComponent<MeshFilter>())
        {
            if (!child.gameObject.GetComponent<MeshCollider>())
            {
                child.gameObject.AddComponent<MeshCollider>();
            }
        }
        child.gameObject.tag = "CenterObject";
        yield return null;
    }
}

即便如此,如果您正在循环使用大量儿童,则可能仅仅是性能问题。

答案 2 :(得分:1)

除了修复你的Coroutine的答案:

协同程序并不是真正的多线程!这就是为什么如果Coroutine中有一项长期任务,你的应用程序会冻结的原因。

Coroutines的yield return只是让你很容易/懒得做一个快速动画或类似的东西,因为Coroutines有点&#34;记得&#34;他们离开并继续从这一点开始(用简单的话说)所以你可以显然运行很多东西&#34; parallel&#34;。但它仍然在同一个线程中运行,所以实际上它似乎只是并行执行,因为一切都在两帧之间执行。

如果您真的想要在另一个线程中执行一项耗时的任务,而不是查看自Unity 2017以来Unity async await的真正多线程。

然而Unity 线程保存意味着大多数API只能在主线程中使用...