MonoBehavior中协程详解

一、Unity是否支持多线程?

        Unity是支持多线程的,只是新开线程无法访问Unity相关对象的内容

Tips:Unity中的多线程 要记住关闭


二、协同程序是什么?

1.含义

         协同程序简称协程它是“假”的多线程,它不是多线程

2.作用

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

3.使用场景

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


三、协同程序和线程的区别

新开一个线程是独立的一个管道,和主线程并行执行
新开一个协程是在原线程之上开启,进行逻辑分时分步执行


四、协程的使用

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

1.申明协程函数

(1)返回值为IEnumerator类型及其子类
(2)函数中通过 yield return 返回值; 进行返回

2.开启协程函数

IEnumerator ie = MyCoroutine(1, "123");
StartCoroutine(ie);
Coroutine c1 = StartCoroutine( MyCoroutine(1, "123") );
Coroutine c2 = StartCoroutine( MyCoroutine(1, "123"));
Coroutine c3 = StartCoroutine( MyCoroutine(1, "123"));
IEnumerator MyCoroutine(int i, string str)
{
    print(i);
    //关键点二: 协程函数当中 必须使用 yield return 进行返回
    yield return null;
    print(str);
    yield return new WaitForSeconds(1f);
    print("2");
    yield return new WaitForFixedUpdate();
    print("3");
    //主要会用来 截图时 会使用
    yield return new WaitForEndOfFrame();
    
    while(true)
    {
        print("5");
        yield return new WaitForSeconds(5f);
    }
}

3.关闭协程

(1)关闭所有协程

StopAllCoroutines();

(2)关闭指定协程

StopCoroutine(c1);


五、yield return 不同内容的含义

1.下一帧执行

yield return 数字;
yield return null;

        在Update和LateUpdate之间执行

2.等待指定秒后执行

yield return new WaitForSeconds(秒);

        在Update和LateUpdate之间执行

3.等待下一个固定物理帧更新时执行

yield return new WaitForFixedUpdate();

        在FixedUpdate和碰撞检测相关函数之后执行

4.等待摄像机和GUI渲染完成后执行

yield return new WaitForEndOfFrame();

        在LateUpdate之后的渲染相关处理完毕后之后

5.一些特殊类型的对象 比如异步加载相关函数返回的对象

        一般在Update和LateUpdate之间执行

6.跳出协程

yield break;


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

协程开启后
(1)组件和物体销毁,协程不执行

(2)物体失活协程不执行

(3)组件失活协程执行


七、练习题一

1.题目

        利用协程制作一个计秒器

2.实现

IEnumerator MyCoroutine()
{
    int time = 0;
    while(true)
    {
        print(time + "秒");
        ++time;
        yield return new WaitForSeconds(1);
    }
}
StartCoroutine(MyCoroutine());


八、练习题二

1.题目

        请在场景中创建100000个随机位置的立方体,让其不会明显卡顿

2.实现

private void Update()
{
    if( Input.GetKeyDown(KeyCode.Space) )
    {
        StartCoroutine(CreateCube(100000));
    }
}

IEnumerator CreateCube(int num)
{
    for (int i = 0; i < num; i++)
    {
        GameObject obj = GameObject.CreatePrimitive(PrimitiveType.Cube);
        obj.transform.position = new Vector3(Random.Range(-100, 100), Random.Range(-100, 100), Random.Range(-100, 100));
        if (i % 1000 == 0)
            yield return null;
    }
}


九、协程原理

1.协程的本质

(1)协程函数本体
(2)协程调度器

协程本体就是一个能够中间暂停返回的函数

协程调度器是Unity内部实现的,会在对应的时机帮助我们继续执行协程函数

Unity只实现了协程调度部分,协程的本体本质上就是一个 C#的迭代器方法

2.协程本体是迭代器方法的体现

(1)协程函数本体
        如果我们不通过开启协程方法执行协程,Unity的协程调度器是不会帮助我们管理协程函数。

但是我们可以自己执行迭代器函数内容
        //ie.MoveNext();//会执行函数中内容遇到 yield return为止的逻辑
        //print(ie.Current);//得到 yield return 返回的内容

        //ie.MoveNext();
        //print(ie.Current);

        //ie.MoveNext();
        //print(ie.Current);

        //ie.MoveNext();
        //TestClass tc = ie.Current as TestClass;
        //print(tc.time);

        MoveNext 返回值 代表着 是否到了结尾(这个迭代器函数 是否执行完毕)

3.协程调度器

继承MonoBehavior后开启协程
相当于是把一个协程函数(迭代器)放入Unity的协程调度器中帮助我们管理进行执行
具体的yield return 后面的规则 也是Unity定义的一些规则

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值