0

I have kind of huge miss-understanding - how to calculate something heavy in separate thread, get result, and "continue main routine". I'm developing board game, and tasks of "board checking" and "AI thinking" takes cpu hard, so I'm trying to separate calculations to another thread.

I'm not .NET programmer, mostly c++, I read a lot about coroutines and threads in c sharp and unity3d for last 4 days, but now i just got full mess in my head, completely loosing any kind of "what to do".

I found, that unity still use .NET2, so no TPL or TPLv3 can be used. I was looking for Foundation Tasks library ( https://github.com/NVentimiglia/Unity3d-Foundation/wiki/4)-Unity-Tasks ), but cun't understand how to use it for my case. I'm looking at examples and feel myself idiot. I was trying to write mix of threads and coroutines by myself, but now just got full code messy without any working results =(

Can anybody give my any simple example of my case: when unity object do some have calculations in other thread, getting result of it's work and continues "normal behaviour".

Fattie
  • 27,874
  • 70
  • 431
  • 719
abrakadobr
  • 11
  • 6
  • There are absolutely no threads, whatsoever, in Unity3D. This information is widely available on millions of QA. (You mention "coroutines" - they have utterly no connection, in any way, to threads. Coroutines relate to waiting for the next graphics frame and have no connection whatsoever to processing.) – Fattie Jun 11 '16 at 12:44
  • Secondly note that it is inconceivable you will need a "separate CPU" to do the "AI" for a board game. It's not in the bounds of reality, it would be out by a factor of 10,000. – Fattie Jun 11 '16 at 12:45
  • Thirdly, you need only google "https://www.google.com/search?q=asset+store+threading" to instantly find the threading packages for Unity. If (incredibly) you need to do math calculations or the like, that's your answer. (It is inconceivable you would write your own threading system from scratch - no more than you would write the renderer or physics from scratch!) – Fattie Jun 11 '16 at 12:46
  • Note that back in .NET2, we mostly used `BackgroundWorker` to handle work like this - using raw `Thread`s is a huge pain. `BackgroundWorker` gives you a simple way of marshalling results and errors back to the source synchronization context, for example - something you can exploit quite easily to make your own pseudo-tasks on top of the co-routine framework in Unity. – Luaan Jun 13 '16 at 13:29
  • @Programmer Have you ever tried writing any kind of AI for a boardgame, or any other game for that matter? Do you think it's a good idea to only start calculating when the player pressed "End turn"? Do you think it's a good idea to stop the player's game for 10 seconds, when 2 seconds would be possible? Or zero? – Luaan Jun 13 '16 at 15:53

1 Answers1

0

I found solution, mixed of threads and coroutines.

I don't really like threads style programming in C#, cuz getting back result it not clearly understandable - code is not nice.

So, this is my solution, using Foundation.Tasks

Imagine for example, we have some MonoBehaviour child class, doing some heavy calculations.

code before UnityTasks

public class ExampleClass : MonoBehaviour {
  public bool MyHeavyCalculator(bool exampleArg)
  {
    //loong and heavy calculations
  }

  public void SomeFunc()
  {
    //and here we get freezing
    if (MyHeavyCalculator(boolArg))
    {
      //unfreeze here
    }
  }
}

code, using UnityTask from Foundation

//in my case, heavy calculations are static in another class
public static class Calculator
{
  public static bool DoHeavy(bool exampleArg)
  {
    //loong and heavy calculations
  }

}

public class ExampleClass : MonoBehaviour {

  IEnumerator coroutineSomeFunc()
  {
    bool result = false;
    //code to show "thinkng sign"
    UnityTask t = UnityTask.Run( () => {
      //and no freesing now
      result = Calculator.DoHeavy(myArg);
    });
    yeild return t;
    //code to hide "thinkng sign"
    if (result)
    {
      //continue game flow
    }
  }

  public void SomeFunc()
  {

    StartCoroutine(coroutineSomeFunc());
  }
}

Also, Foundation.Tasks lets me chose strategy (coroutine, background thread) easyly, also i'm getting result of calculations without any problems, and my code is nice and easy to understand (imho)

abrakadobr
  • 11
  • 6
  • https://stackoverflow.com/a/54184457/294884 threading + frame based system causes vast confusion – Fattie Jan 14 '19 at 15:53