通过调用Coroutines来解决Unity3D性能问题

时间:2015-10-27 06:35:09

标签: c# performance unity3d coroutine

我正在用AI进行国际象棋比赛。

有一些功能可以处理游戏规则,例如DoMove()DoSkill()

但由于某些原因(大部分用于显示炫酷效果),函数返回类型为IEnumerator而不是void。所以函数的用法如下所示:

yield return StartCoroutine(DoSkill());

现在问题来了,AI是一项繁重的工作,但我听说Unity的Coroutines不适合重度计算。当我将函数更改为IEnumerator时,AI的速度显然变得非常慢。

我确信没有任何WaitForSeconds(someFloat)将在AI中执行(我使用一些参数& if / else跳过它),看起来表现真的很差如果我一次又一次地呼叫StartCoroutine

我能想到的可能解决方案是编写两种DoSkill()函数,一种返回类型为void,另一种是IEnumerator。但这真的不是一个好方法。因为我必须保持很多类似的功能,而且它也很难看。

任何建议都将不胜感激。

1 个答案:

答案 0 :(得分:0)

协同程序并不神奇 - 它们是一种让函数在执行中保持放弃控制的方式,并在下次被抽出时继续执行。它们确实存在,允许开发人员避免编写多线程代码。

它们不适用于繁重计算的原因是它们在主线程中执行,因此任何长时间运行的代码都会有效地降低帧速率。

它们可以在您知道可以执行小的确定性工作并且下次推迟的情况下工作 - 例如处理下载的字节流,复制数据等。因此,如果您在60FPS下平稳运行,您知道您有16 ms在一个框架中做所有事情,繁重的计算可能会在时间上变化,很难提前知道。如果你总共超过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();
  }
}