Unity3D 调用协程的性能问题
Unity3D performance issue by calling Coroutines
我正在做一个有 AI 的国际象棋游戏。
有一些处理游戏规则的函数,例如DoMove()
、DoSkill()
。
但由于某些原因(主要是为了显示炫酷的效果),函数return类型是IEnumerator
而不是void
。所以该函数的用法如下所示:
yield return StartCoroutine(DoSkill());
问题来了,AI是个重活,但是听说Unity的Coroutines不适合重计算。当我将功能更改为IEnumerator
时,AI的速度明显变慢了。
我确定没有任何 WaitForSeconds
(someFloat) 会在 AI 中执行(我使用了一些参数 & if/else 来跳过它),它看起来就像性能连续不断的叫StartCoroutine
真的很可怜
我能想到的解决办法是写两种DoSkill()
函数,一种return类型是void
,另一种是IEnumerator
。但这确实不是一个好方法。因为我要维护很多类似的功能,而且也很丑
如有任何建议,我们将不胜感激。
协程并没有什么神奇的——它们是一种让函数在执行过程中不断放弃控制,并在下次被抽取时继续执行的方法。它们的存在实际上是为了让开发人员避免编写多线程代码。
它们不适用于繁重计算的原因是它们是在主线程中执行的,因此任何长 运行ning 代码都会有效地降低帧率。
他们确实在你知道你可以做一些确定性的小工作并推迟到下一次的地方工作——比如处理下载的字节流、复制数据等。所以如果你 运行 顺利地60FPS 你知道你有 16 毫秒的时间来完成一帧中的所有事情,繁重的计算可能会随时间变化并且很难提前知道。如果您总共超过 16 毫秒(包括您的计算在内的所有内容),FPS 将会减慢并且游戏会出现抖动。
我建议您 运行 在后台线程中进行计算。基本上是:
using UnityEngine;
using System.Threading;
public class ChessAI : MonoBehaviour
{
Thread aiThread;
void StartAI()
{
aiThread = new Thread(new ThreadStart(AIThread));
aiThread.Start();
}
void AIServer()
{
// do stuff here - be careful of accessing data being changed by main thread
}
public void OnApplicationQuit()
{
// It is crucial in the editor that we stop the background thread when we exit play mode
aiThread.Abort();
}
}
我正在做一个有 AI 的国际象棋游戏。
有一些处理游戏规则的函数,例如DoMove()
、DoSkill()
。
但由于某些原因(主要是为了显示炫酷的效果),函数return类型是IEnumerator
而不是void
。所以该函数的用法如下所示:
yield return StartCoroutine(DoSkill());
问题来了,AI是个重活,但是听说Unity的Coroutines不适合重计算。当我将功能更改为IEnumerator
时,AI的速度明显变慢了。
我确定没有任何 WaitForSeconds
(someFloat) 会在 AI 中执行(我使用了一些参数 & if/else 来跳过它),它看起来就像性能连续不断的叫StartCoroutine
真的很可怜
我能想到的解决办法是写两种DoSkill()
函数,一种return类型是void
,另一种是IEnumerator
。但这确实不是一个好方法。因为我要维护很多类似的功能,而且也很丑
如有任何建议,我们将不胜感激。
协程并没有什么神奇的——它们是一种让函数在执行过程中不断放弃控制,并在下次被抽取时继续执行的方法。它们的存在实际上是为了让开发人员避免编写多线程代码。
它们不适用于繁重计算的原因是它们是在主线程中执行的,因此任何长 运行ning 代码都会有效地降低帧率。
他们确实在你知道你可以做一些确定性的小工作并推迟到下一次的地方工作——比如处理下载的字节流、复制数据等。所以如果你 运行 顺利地60FPS 你知道你有 16 毫秒的时间来完成一帧中的所有事情,繁重的计算可能会随时间变化并且很难提前知道。如果您总共超过 16 毫秒(包括您的计算在内的所有内容),FPS 将会减慢并且游戏会出现抖动。
我建议您 运行 在后台线程中进行计算。基本上是:
using UnityEngine;
using System.Threading;
public class ChessAI : MonoBehaviour
{
Thread aiThread;
void StartAI()
{
aiThread = new Thread(new ThreadStart(AIThread));
aiThread.Start();
}
void AIServer()
{
// do stuff here - be careful of accessing data being changed by main thread
}
public void OnApplicationQuit()
{
// It is crucial in the editor that we stop the background thread when we exit play mode
aiThread.Abort();
}
}