首页 > 其他分享 >Unity 协程详解

Unity 协程详解

时间:2023-07-14 17:55:37浏览次数:33  
标签:return 函数 yield Unity 详解 new 协程

  在程序开发时,光是了解协程怎么用是远远不够的,因为当程序出现一些有关于协程的错误时,理解协程的原理就十分有必要性了。

1.协程使用的一些问题

  我们知道如果在Unity中编写一个死循环,会造成运行游戏时整个Unity编辑器卡死,而协程函数在使用时好像是可以与Update函数并行不斥的,那如果在一个协程函数里面编写一个死循环会怎么用呢?答案也是程序会卡死。

  所以,我们知道了,协程函数并不是一个独立的执行单元,它与Update函数一样,被Unity依次执行。一旦有一个发生了死循环,游戏将会卡死。简而言之,协程不是线程。

  从上面可以看到,协程非常像一个自定义的Update函数,只不过内部含有延时逻辑。而有意思的是,Mono的生命周期函数例如Start和Update是可以支持协程调用的,只是不需要使用StartCoroutine就可以直接调用。

public class Coroutine : MonoBehavior{
    IEnumerator Start(){
          Debug.log(1);
          yield return new WaitForSeconds(1);
          Debug.log(2);
          yield return new WaitForSeconds(1);      
    }
}

  上述的Start方法并不是主动调用的,而是被Unity引擎识别并调用的,这里把Start的返回值void改成了IEnumerator,也同样被Unity识别了。

2.迭代器

  虽然协程是Unity提供的,但是IEnumrator则是C#的语法,所以我们要弄清楚协程就先要知道这两个玩意的机制。事实上,IEnumrator与yield配合实现了一种叫做“可重入函数”的机制,也就是函数可以被打断一会,之后再执行的机制。

public class Itr:MonoBehaviour{
    IEnumerator<int> HelloWorld(){
          transform.position = new Vector3(1,0,0);
          yield return 233;
          transform.position = new Vector3(2,0,0);
          yeild return 666;
    }

     void Start(){
          IEnumerator<int> e  = HelloWorld();
          while(){
                 if(!e.MoveNext()){
                     break;    
                 }else{
                           Debug.log("yield 返回值"+e.Current);
                           Debug.log("当前位置"+transform.position);        
                 }        
          }
    }
}        

  这里HelloWorld就是一个可重入函数,在初次执行时会在第一个yield处卡住,返回值是一个IEnumrator对象,之后程序会把他保存在e变量中。每次调用e.MoveNext()方法时会让函数继续执行到下一个yield处,执行到最后一个yield后,函数彻底执行完毕,并且返回false;

  每次执行一步,还可以从变量e中获取到中断时的返回值,即e.Current。这个返回值将非常有用。

  yield在生命周期的运行时机:我们知道要使用协程的脚本必须先继承自MonoBehaviour。其中一个原因就是在协程的yield也在Mono生命周期中,且在Update与LatedUpdate之间。以下是常用的

    yield return null; 暂停协程等待下一帧继续执行

    yield return 0或其他数字; 暂停协程等待下一帧继续执行

    yield return new WairForSeconds(时间); 等待规定时间后继续执行

    yield return StartCoroutine("协程方法名");开启一个协程(嵌套协程)

    yield return new WaitForFixedUpdate():等到下一个固定帧数更新

    yield return new WaitForEndOfFrame():等到所有相机画面被渲染完毕后更新

3.协程的延时执行原理

IEnumerator<int> HelloWorld(){
    float helloTime = 0;
    transform.position = new Vector3(1,0,0);
    helloTime = Time.time+1;
    while(Time.time<helloTime){
        // 返回值没用
        yield return 1;
    }
}

  上述代码中,Update函数每帧都会调用协程函数,而协程函数自身会用循环控制运行的进度,如果时间不到就立即中断,最终实现了定时运行的效果。这一实现方法从原理上与Unity中一致(Unity源码不开放)。

 

 

 

 

 

  

标签:return,函数,yield,Unity,详解,new,协程
From: https://www.cnblogs.com/CatSevenMillion/p/17554490.html

相关文章

  • Unity下载安装包并进行安装
    项目上要做更新,还没学热更新,要做到游戏内部下载安装包并进行安装的效果,项目不采用Url转跳默认下载器的方式。Url转跳下载方式Application.OpenURL(URL);用这个转跳你的Nginx下载路径就行了,项目上不让用这种方式Unity内下载安装包Unity调用安卓安装安装包参考文章待整理......
  • Linux命令----modprobe命令详解
    【原文链接】Linux命令----modprobe命令详解一、modprobe命令的作用加载内核模块:使用modprobe命令可以加载指定的内核模块到运行中的内核中。加载内核模块可以在运行时添加新的功能、驱动程序或修改内核行为。解决模块依赖关系:modprobe命令可以自动解决内核模块之间的依......
  • 苹果iOS App Store上架操作流程详解:从开发者账号到应用发布
    ​ 很多开发者在开发完iOSAPP、进行内测后,下一步就面临上架AppStore,不过也有很多同学对APP上架AppStore的流程不太了解,下面我们来说一下iOSAPP上架AppStore的具体流程,如有未涉及到的部分,大家可以及时咨询,共同探讨。内容:在完成iOSAPP开发和内部测试后,下一个步骤就是将应......
  • Splay&LCT不怎么详细的详解
    Splay:平衡树的一种,学名伸展树。平衡树首先是一棵二叉搜索树(BST),满足性质:中序遍历单调递增。根据这个性质,很容易在一棵BST上完成以下操作:插入一个数,查询一个数的排名,查询给定排名的数,删除一个数。BST可能是不平衡的,即左右子树相差很大。Splay均摊后是平衡的,即时间复杂度均摊......
  • Linux下chkconfig命令详解(service)
    Linux下chkconfig命令详解(service)一、释义chkconfig命令主要用来更新(启动或停止)和查询系统服务的运行级信息。谨记chkconfig不是立即自动禁止或激活一个服务,它只是简单的改变了符号连接。二、使用语法chkconfig[--add][--del][--list][系统服务]或chkconfig[--level......
  • 2023年iOS App Store上架流程详解(上)
    ​ 在2023年,随着苹果发布机制的微调,有些关于iOSApp上架流程的资料已经过时。本文将根据最新的要求和经验,详细介绍iOSApp上架的流程。1.注册开发者账号首先,您需要注册一个AppleDeveloper的开发者账号。这个账号的年费大约是600多元人民币。注册过程可以在AppleDeveloper......
  • dede织梦标签,dede:arclist用法与详解
    标签名称:arclist标记简介:织梦常用标记,也称为自由列表标记,其中imglist、imginfolist、specart、coolart、autolist都是由该标记所定义的不同属性延伸出来的别名标记。功能说明:获取指定文档列表适用范围:全局使用基本语法:{dede:arclist?flag='h'typeid=''row=''col=''titlelen=......
  • ASP.Net Core Razor+AdminLTE 应用详解
     AdminLTE介绍 一个基于bootstrap的轻量级后台模板,这个前端界面个人感觉很清爽,对于一个大后端的我来说,可以减少较多的时间去承担前端的工作但又必须去独立去完成一个后台系统开发的任务,并且,文档还算比较齐全,对着demo可以完成一个基本的前端框架搭建了。大家如有更为好......
  • python之struct详解
    用处按照指定格式将Python数据转换为字符串,该字符串为字节流,如网络传输时,不能传输int,此时先将int转化为字节流,然后再发送;按照指定格式将字节流转换为Python指定的数据类型;处理二进制数据,如果用struct来处理文件的话,需要用’wb’,’rb’以二进制(字节流)写,读的方式来处理......
  • Spring的生命周期详解
    Spring的生命周期Spring框架是一个非常流行的Java企业级开发框架,它提供了很多强大的功能,包括依赖注入、AOP、事务管理等。在使用Spring框架时,了解Spring的生命周期非常重要,可以帮助我们更好地理解Spring框架的工作原理。Spring的生命周期可以分为三个阶段:实例化阶段、初始化阶段......