Unity 协同程序-1

264 阅读4分钟

Unity多线程

unity支持多线程。且线程开启方式与C#中一样。不过子线程无法访问Unity相关对象的内容!包括物体,transform,哪怕Unity的Random都不行。另外子线程需要手动关闭!!!

public class Test : MonoBehaviour
{
    private Thread thread;

    private void Start()
    {
        thread = new Thread(() =>
        {
            while (true)
            {
                print(123);
                Thread.Sleep(1000);
            }
        });
        //开启线程
        thread.Start();
    }

    private void OnDestroy()
    {
    	//关闭线程
        thread.Abort();
    }
}

所以,一般子线程都会被用来做一些耗时的运算,比如A*寻路,网络请求等。当子线程运算结束后,可以将结果放到一个公共内存区,比如一个队列,然后主线程就可以去队列里面获取数据了。

 

协同程序

不是多线程。

作用:

  1. 将代码分时分步执行,不卡主线程。简单的理解就是把可能会让主线程卡顿的耗时逻辑分时分步的执行。

主要使用场景:

  1. 异步加载文件
  2. 异步下载文件
  3. 场景异步加载
  4. 批量创建时防止卡顿

协程和多线程的区别

多线程:新开一个线程时独立的一个管道,和主线程并行执行。

协程:新开一个协程是在主线程上开启,进行逻辑的分时分步执行。本质上只有一个线程。

详细来讲就是:协程函数是在原线程上开启的(一般都是主线程),会将耗时的逻辑分成N个步骤去执行,每次只执行一个步骤,然后会有返回值(决定了什么时候,是否继续下一个步骤),然后协程挂起,主线程继续执行。因为主线程是一个死循环,他会有自己的生命周期函数,所以在上个步骤执行完之后的下一帧,会根据上一个步骤的返回值去判断是否继续执行下一个步骤。同时在执行每个步骤时都可以控制等待时间,即加Delay函数。直到所有步骤执行完。

 

协程的使用

继承MonoBehavior的类都可以开启协程函数。

第一步:申明协程函数。协程函数 有两个关键点:1.返回值为IEnumerator类型及其子类;2.函数中通过yield return返回值进行返回。

IEnumerator Test1()
{

	//这里的协程函数分为了2步,第一步是打印1,然后等待1帧,打印2。
    //第一步
    print(1);
    yield return 1;
    //第二步
    print(2);
    yield return 2;
}

第二步:开启协程函数。

//协程函数是不能狗执行调函数执行的!
//Test1();
//常用的开启方式
StartCoroutine(Test1());

关闭协程

var cor = StartCoroutine(Test1());
//关闭指定协程
StopCoroutine(cor);
//关闭所有协程
StopAllCoroutines();

yield return返回值类型

决定下一步什么时候执行

  1. 下一帧执行:yield return 数字或null。会在update和LateUpdate之间执行
  2. 等待指定秒后执行:yield return new WaitForSeconds(秒)
  3. 等待下一个固定物理帧更新时执行:yield return new WaitForFixedUpdate()。将在FixedUpdate和碰撞检测相关函数之后执行。
  4. 等待摄像机和GUI渲染完成后执行:yield return new WaitForEndOfFrame()。在LastUpdate之后的渲染相关处理完毕后执行。
  5. 一些特殊类型的对象,比如异步加载相关函数的返回对象。会在资源加载完毕之后执行。一般在Update和LateUpdate之间执行。
  6. 跳出协程:yield break;

协程受对象和组件失活销毁的影响

协程开启后,组件和物体销毁,协程不执行;物体失活协程不执行;组件失活协程执行。

在异步加载场景时会受影响,因为异步加载场景完成后会销毁当前场景,导致当前场景的协程后续不执行。

总结

  1. Unity支持多线程,只是新开线程无法访问主线程的Unity相关内容。一般主要进行复杂的逻辑运算或网络消息接收等!注意:Unity中的多线程一定要记住关闭!
  2. 协同程序不是多线程,他是将线程中的逻辑进行分时执行,避免卡顿。
  3. 继承MonoBehavior的类都可以开启协程函数
  4. 开启/关闭协程的方法
  5. yield return返回的内容的含义
  6. 协程只有当组件单独失活时不受影响,其他情况(物体失活/销毁,组件销毁)协程都会停止

qrcode.jpg