我的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";
}
}
答案 0 :(得分:4)
Coroutines在构建它们时似乎有一些开销,如下所述:https://forum.unity.com/threads/startcoroutine-performance-cost.233623/
鉴于您正在实例化对象,我建议这些路径:
答案 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只能在主线程中使用...