统一使用协程像一个线程?

时间:2018-08-26 12:39:49

标签: unity3d coroutine

我有一个耗时的功能,例如...

Debug.Log("A");

void Froze_Function() {
  for(int i=0; i<50000; ++i)
    // take some time...

  Debug.Log("B");
}

Debug.Log("C");

我不希望“ Froze_Function”延迟我的统一程序,所以我希望它在其他线程中运行。

Unity有一个协程,但是我不知道如何正确地使用协程来实现此功能。

请不要说优化我的功能...

2 个答案:

答案 0 :(得分:1)

void Start()
{
    Debug.Log("A");
    StartCoroutine(Froze_Function());
    Debug.Log("C");
}

//Inside a method (class should be MonoBehavour) call: StartCoroutine(Froze_Function()); 

IEnumerator Froze_Function()
{
    float dist;
    for (int i = 0; i < 500; ++i)
    {
        dist = Vector3.Distance(Vector3.up, Vector3.left);
        yield return 0;
    }

        Debug.Log("B");
    yield return 0;
}

答案 1 :(得分:0)

您是将其用作耗时任务的示例,还是实际上需要等待设定的时间?如果您实际上需要等待设定的时间,则IENumerator(协程)中有yield return new WaitForSeconds(n),将等待n秒。 Docs on WaitforSeconds

多线程方法

那表示您也可以为此使用新的线程,具体取决于您要执行的操作。统一处理多个线程时,请记住,您将不能从新线程访问单行为。表示将无法访问诸如gameObject.transform.position等之类的内容。 Debug.Log是一个例外,可以 对其进行访问。如果要编辑gameObject,请使用协程。

这样就很容易启动一个新线程本身,这样做的一个好处是,如果要等待设定的时间而又不损失任何性能的性能,则可以使用Thread.Sleep: / p>

using System.Threading;
public class ThreadStarter
{
   Start()
   {
      Debug.Log("a");
      Thread newThread = new Thread(() => FunctionRunningOnThread());//this function will now execute on the new thread
      newThread.Start();
      Debug.Log("c");
   }

   private void FunctionRunningOnThread()
   {
       Thread.Sleep(5000)//Thread.Sleep is in milliseconds, so this waits 5 seconds
       Debug.Log("B"); //debug.log 
   }
}

这将在5秒钟后打印“ a c”,然后打印“ b”。请记住,尽管要安全地处理竞争条件,锁定变量,所以要在多个线程上安全地安全比在单个线程上工作要困难得多,因此您不必尝试从多个位置进行编辑在同一时间和方式更多的东西。不建议这样做,除非您知道自己在做什么,并且使用协程是更安全的选择。

启动协程 协程函数必须始终为IENumerator类型,并使用StartCoroutine函数进行调用,并始终使用yield return返回一个值,该值可以为null

Start()
{
    Debug.Log("a");
    StartCoroutine(SomeFunction());
    Debug.Log("c";
}

private IENumerator SomeFunction()
{
   yield return new WaitForSeconds(5);//this will wait 5 seconds
   Debug.Log("b");

   //Alternatively you can use this if you want to wait a set of frames
   for(int i = 0; i < 50000; i++)//this will wait 50000 frames
   {
       i++
       yield return new WaitForEndOfFrame();/
   }
}

这也将在5秒钟后打印“ a”,“ c”,然后打印“ b”。这样做的好处是,您仍然可以在协程内部编辑GameObjects,而不必担心线程安全。