我在和人工智能玩国际象棋。
有一些处理游戏规则的函数,如DoMove()、DoSkill()。
但是由于某些原因(大多数是为了显示酷效果),函数返回类型是IEnumerator而不是void。因此函数的用法如下所示:
yield return StartCoroutine(DoSkill());现在问题来了,人工智能是一个繁重的工作,但我听说,统一的协同不适合于繁重的计算。当我将函数转换为IEnumerator时,AI的速度明显变慢了。
我确信在AI中不会执行任何WaitForSeconds(someFloat) (我使用一些参数& if/else跳过它),如果我一次又一次地调用StartCoroutine,性能就会很差。
我认为可能的解决方案是编写两种DoSkill()函数,一种是返回类型为void,另一种是IEnumerator。但这真的不是个好办法。因为我必须保持很多类似的功能,而且它也很难看。
如有任何建议,将不胜感激。
发布于 2015-10-27 07:21:14
Coroutines没有什么神奇之处--它们是一种让功能不断放弃控制的方式--在执行过程中,并在下一次被抽走的时候继续。它们的存在实际上是为了让开发人员避免编写多线程代码。
它们不适用于繁重计算的原因是它们是在主线程中执行的,因此任何长时间运行的代码都会有效地扼杀您的帧速率。
它们会在你知道你可以做一小部分确定性工作的地方工作,并推迟到下一次--比如处理下载的字节流、复制数据等。因此,如果你在60 for的时候运行得很顺利,你知道你有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();
}
}https://stackoverflow.com/questions/33361323
复制相似问题