简体   繁体   中英

Unity3D performance issue by calling Coroutines

I'm doing a chess game with AI in it.

There are some functions that handle the rule of game, like DoMove() , DoSkill() .

But for some reasons (most for display cool effects), the function return type is IEnumerator instead of void . So the usage of the function look like this :

yield return StartCoroutine(DoSkill());

Now the problem comes, AI is a heavy work, but I've heard that Unity's Coroutines is not suitable for heavy calculating. When I change functions to IEnumerator , the speed of AI obviously getting very slow.

I'm sure that there isn't any WaitForSeconds (someFloat) will be execute in AI(I use some parameter & if/else to skip it), it just seems like the performance is really poor if I continuously call StartCoroutine again and again.

The possible solution I can think of is write two kind of DoSkill() funtion, one's return type is void , the other is IEnumerator . but it's really not a good way. because I have to maintain lots of similar functions, and it's ugly too.

Any suggestions would be greatly appreciated.

Coroutines are nothing magical - they are a way to have a function keep giving up control mid-execution, and continuing on next time they are pumped. They exist really to allow developers to avoid writing multi-threaded code.

The reason they don't work for heavy calculations is that they are executed in the main thread, so any long running code would effectively kill your frame rate.

They do work where you know you can do a small deterministic pieces of work and defer for next time - such as processing downloaded byte streams, copying data, etc. So if you are running smoothly at 60FPS you know you have 16 ms to do everything in a frame, and heavy calculations might be variable in time and hard to know ahead. If you exceed 16 ms in total (everything including your calculation) the FPS will slow down and the game will appear jerky.

I suggest in your case you run the calculations in a background thread. It's basically:

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();
  }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM