Unity中协程(Coroutine)的使用简要

如有谬误,欢迎指正
上篇博客中提到unity中的异步加载实际上就是运用的协程,今天我们就来探讨下协程又是什么东东.
我们先来说说协程和线程的区别吧.通俗的讲(当然你要是让我扒底层的讲我也讲不出来[手动无奈]),线程就相当于流水线,我们平常的程序运行相当于一条流水线在不停的生产产品,多线程就是多条流水线同时开工。协程不同,协程就是在一条流水线正常生产产品的基础上,额外的做了一些其他产品的生产工作。
在unity中,协程的主要作用就是将一件很复杂的事情,分开来做,比如加载一个很大的场景,如果我们将加载场景的工作放在一帧内完成,就会出现卡机的情况,如果我们把这个事情,分成若干帧来做,每帧加载一点,这样既不会影响其他操作,又能顺利的加载新场景,机子也就不会卡住了(当然,不管怎么说,实际上我们还是在加载场景,所有肯定还是要有性能开销的)。
接下来我们就说说怎么用,其实并不难,首先定义一个返回值为 IEnumerator 的函数,然后在适当的位置用 StartCoroutine()调用即可,上代码:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class TestScripe : MonoBehaviour {

	
	void Start () {
        StartCoroutine(Test(5));//调用协程函数
     //   StartCoroutine("Test",5);
    }
	
	void Update () {
        Debug.Log("开始一帧");
        Debug.Log("完成一帧");
    }

    //协程函数
    IEnumerator Test(int max)
    {
        for (int i = 0; i < max; i++)
        {
            Debug.Log(i);
            yield return null;//表示下一帧再继续执行后面的代码
        }
    }
}

结果如下:

从输出结果我们可以看出,虽然在start函数中调用了Test函数,但是Test函数中的for循环并没有一次性循环完,而是当Update函数完成一次(也就是完成一帧)后才继续向下运行一步,直至完成整个for循环。试想如果这个for循环是个很复杂的计算算法,一次性完成很耗时间(卡机),使用协程是不是就轻松多了呢,这就是上文所说的将一件复杂的事情,分开来做了。
上述脚本中 yield return null;语句表示下一帧继续执行后面的代码,那么它是不是严格的按照在update函数完成后执行呢?除了能够实现“下一帧继续执行”的功能外,协程还有没有其他功能?我们来看看unity的官方文档:

我们可以看出官方文档中,在unity脚本生命周期内,多处有yield出现,其中yield null就是紧跟在Update函数之后,这也恰好符合我们的输出结果。那么其他的yield表示什么意思,在此引用另一篇博客内容,以供参考:

调用协程的方法有两种,分别是StartCoroutine(/这里直接调用方法,添加参数/),另一种是StartCoroutine(/这里填写”字符串的方法名字”,方法参数/)。第一种方法的优势在于可以调用多个参数的方法,后一种方法只能调用不含参数或只包含一个参数的协程方法。但是第一种方法不能通过StopCoroutine(/这里填写”字符串的方法名”/)来结束协程,只能通过StopAllCoroutines来结束。后一种则可以通过StopCoroutine来结束对正在执行的协程的调用。

协程在实现过程中我们需要注意yield调用的时机,执行较为复杂的计算时,如果在时间上没有严格的先后顺序,我们可以每帧执行一次循环来完成计算,或者每帧执行指定次数的循环来防止在程序运行中出现的卡顿现象。

yield return null; // 下一帧再执行后续代码
yield return 0; //下一帧再执行后续代码
yield return 6;//(任意数字) 下一帧再执行后续代码
yield break; //直接结束该协程的后续操作
yield return asyncOperation;//等异步操作结束后再执行后续代码
yield return StartCoroution(/某个协程/);//等待某个协程执行完毕后再执行后续代码
yield return WWW();//等待WWW操作完成后再执行后续代码
yield return new WaitForEndOfFrame();//等待帧结束,等待直到所有的摄像机和GUI被渲染完成后,在该帧显示在屏幕之前执行
yield return new WaitForSeconds(0.3f);//等待0.3秒,一段指定的时间延迟之后继续执行,在所有的Update函数完成调用的那一帧之后(这里的时间会受到Time.timeScale的影响);
yield return new WaitForSecondsRealtime(0.3f);//等待0.3秒,一段指定的时间延迟之后继续执行,在所有的Update函数完成调用的那一帧之后(这里的时间不受到Time.timeScale的影响);
yield return WaitForFixedUpdate();//等待下一次FixedUpdate开始时再执行后续代码
yield return new WaitUntil()//将协同执行直到 当输入的参数(或者委托)为true的时候…如:yield return new WaitUntil(() => frame >= 10);

原文在此:https://blog.csdn.net/beihuanlihe130/article/details/76098844

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

五星出东方.

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值