当前位置: 首页 > news >正文

Unity3D协程的使用

系列文章目录

Unity知识点


文章目录

  • 系列文章目录
  • 前言
  • 一、协程是什么?
  • 二、协程的原理
    • 2-1. 协程的实现
    • 2-2 效果如下
    • 2-3 协程的返回值
    • 2-4 协程的调用
    • 2-5 协程提供的延迟的类有下列几种
    • 2-6 重写 WaitForSeconds
    • 2-7 超时处理或某种条件执行
    • 2-8 yield return Coroutine 协程执行完毕后执行后面代码
    • 2-9 外接协程方法
  • 总结

前言

记录一下协程怎么使用的
如果觉得本篇文章有用别忘了点个关注,关注不迷路,持续分享更多Unity干货文章。


提示:以下是本篇文章正文内容,下面案例可供参考

一、协程是什么?

协程就相当于C#的线程。

Unity3D是支持多线程的,只是线程不能访问主线程中的对象,虽然说线程不能访问主线程中的对象,但是可以将一些复杂的算法计算、网络连接等逻辑抛给一个线程去处理,将处理的数据放到公共的内存模块中。Unity3D主线程就可以使用了。

那么协程是什么呢,协程就是Unity针对上面的问题提出的解决方案,协程又叫做协同程序,使用的场景主要有资源、场景的异步加载,但是可以访问主线程中的对象。

协程的本质是迭代器,能够暂停协程执行,暂停后立即返回主函数,执行主函数剩余的部分,直到中断执行完成后,从中断指令的下一行继续执行协程剩余的函数,函数全部执行完成,协程结束。由于中断执行的出现,可以将一个函数分割成多个帧中去执行

二、协程的原理

协程中的所有初始代码,从协程开始到中断执行的位置,可以中断,协程代码中的其他部分,也就是中断执行后面的代码将出现在Unity主循环DelayeCallManager中。

协程由 C# 编译器自动生成的类实例提供支持。

此对象用于跟踪单个方法的多次调用之间的协程状态。

因为协程中的局部作用域变量必须在 yield 调用中保持一致,所以这些局部作用域变量将被保存到上一级的生成的它们的类中,从而保证在协程的存活期内保留在堆上的地址分配。

该对象还会跟踪协程的内部状态:它会记住协程暂停后必须从代码中的哪一点恢复。

因此,启动协程引起的内存压力等于固定开销成本加上其局部变量的消耗。

启动协程的代码将构造并调用此对象,然后 Unity 的DelayedCallManager在每当满足协程的暂停条件时再次调用此对象。

由于协程通常在其他协程之外启动,因此它们的执行成本将分担到上述两个位置,这两个位置又叫做协程函数和协程调度器。

2-1. 协程的实现

代码如下

usingSystem.Collections;usingSystem.Collections.Generic;usingUnityEngine;publicclassCoroutine_IEmator:MonoBehaviour{// Start is called before the first frame updatevoidStart(){Debug.Log("协程之前执行的打印");StartCoroutine(enumerator());Debug.Log("协程之后执行的打印");}publicIEnumeratorenumerator(){Debug.Log("开始协程了");yieldreturnnewWaitForSeconds(2f);//等待2秒Debug.Log("等了两秒之后的打印");}}

2-2 效果如下


PS:这个例子演示了,协程的执行顺序,协程的写法,协程的调用

协程写法:
(1)声明是IEnumerator 迭代器类型返回值
(2)返回值为yield return new,也就是中断程序,就跟int的返回值是0123一样,没有返回值会报错
(3)执行中断程序后面的函数

2-3 协程的返回值

2-4 协程的调用

usingSystem.Collections;usingSystem.Collections.Generic;usingUnityEngine;publicclassCoroutine_IEmator:MonoBehaviour{privatevoidAwake(){//协程的调用如下//调用协程使用StartCoroutine(m_Ien());//调用协程还可以这么写StartCoroutine(“m_Ien”);//终止协程用StopCoroutine(m_Ien());//终止协程还可以这么写StopCoroutine(“m_Ien”);//声明协程再终止协程,mCoroutine = StartCoroutine(m_Ien()); StopCoroutine(mCoroutine);//终止所有协程StopAllCoroutines();//StartCoroutine("enumerator"); //这种开启协程可以终止//StopCoroutine("enumerator"); //可以终止StartCoroutine(enumerator());//这种开启协程终止不了StopCoroutine(enumerator());//终止不了}// Start is called before the first frame updatevoidStart(){//Debug.Log("协程之前执行的打印");////StartCoroutine(enumerator());//Debug.Log("协程之后执行的打印");}publicIEnumeratorenumerator(){Debug.Log("开始协程了");yieldreturnnewWaitForSeconds(2f);//等待2秒Debug.Log("等了两秒之后的打印");}}

2-5 协程提供的延迟的类有下列几种

2-6 重写 WaitForSeconds

代码如下

/// <summary>/// 任务扩展/// </summary>publicstaticclassTaskExtendC{staticpublicIEnumeratorWaitForSeconds(floatsecond){DateTimeinit_dt=DateTime.Now;TimeSpantime;while(true){time=DateTime.Now-init_dt;if(time.TotalSeconds<=second){yieldreturnnull;}else{break;}}}}

调用的方法和unity差不多

如果超时或者符合某种条件就继续执行怎么改动呢?

2-7 超时处理或某种条件执行

代码如下

/// <summary>/// 超时扩展/// 加了一个回调,每次都检查是否为true,true则等待/// </summary>staticclassTaskExtendCC{publicdelegateboolCondDelegate();staticpublicIEnumeratorWaitForSeconds(floatsecond,CondDelegatecond=null){DateTimeinit_dt=DateTime.Now;TimeSpantime;while(true){time=DateTime.Now-init_dt;if(time.TotalSeconds<=second&&!cond()){yieldreturnnull;}else{break;}}}}

2-8 yield return Coroutine 协程执行完毕后执行后面代码

示例如下

usingSystem.Collections;usingSystem.Collections.Generic;usingUnityEngine;publicclassWaitForEndOfAni:IEnumerator{AnimationStatem_animState;publicWaitForEndOfAni(AnimationStateanimState){m_animState=animState;}//=> throw new System.NotImplementedException();publicobjectCurrent{get{returnnull;}}publicboolMoveNext(){returnm_animState.enabled;}publicvoidReset(){}}

核心代码就是判断 m_animState.enabled 是否播放完成
测试代码如下

IEnumeratorDoTest(){Animationanim=GetComponentInChildren<Animation>();AnimationStateanimAttack=anim["attack"];animAttack.speed=0.1f;AnimationStateanimHit=anim["hit"];animHit.speed=0.1f;AnimationStateanimDie=anim["die"];animDie.speed=0.1f;Debug.Log("1.开始播放攻击动画。"+Time.time*1000);anim.Play(animAttack.name);yieldreturnStartCoroutine(newWaitForEndOfAnim(animAttack));Debug.Log("2.开始播放受击动画。"+Time.time*1000);anim.Play(animHit.name);yieldreturnStartCoroutine(newWaitForEndOfAnim(animHit));Debug.Log("3.开始播放死亡动画。"+Time.time*1000);anim.Play(animDie.name);yieldreturnStartCoroutine(newWaitForEndOfAnim(animDie));}

2-9 外接协程方法

privateCoroutinecoroutine;// Start is called before the first frame updatevoidStart(){if(coroutine!=null)StopCoroutine(coroutine);coroutine=StartCoroutine(FromWebRequest(textAsset.text,treeainTrans));}

总结

这篇文章详细讲解了Unity3D的协程的原理以及使用。

以及重写协程程序的返回值和自定义协程返回值。

对于某些代码来说难度比较高,推荐多理解多练习。

http://www.jsqmd.com/news/1257223/

相关文章:

  • 车衣防晒膜建筑遮阳膜座椅镀膜厂家哪家好?2026欧德龙(杭州保通科技实业有限公司)靠谱功能膜甄选:汽车车衣生产制造/车窗 - 栗子测评
  • DETR训练实践以及自动预标注脚本、测试可视化脚本
  • 2026英语培训行业口碑靠谱知名GEO优化公司筛选与推荐 头部服务商对比+合作避坑全指南 - 行业观察网
  • 2026年7月海尔冰箱全国统一24小时售后服务专属热线电话公示最新说明 - 全国网点服务中心
  • MLOps 弹性伸缩:自动扩缩容与 GPU 利用率优化
  • 多轮对话系统崩溃前夜:3个被90%团队忽略的提示词设计漏洞及紧急修复指南
  • 旧运动服回收靠谱吗?爱宝拉高价上门免费取件真相揭秘 - 快递物流资讯
  • 2026 年 7 月新发布:益阳正规的百鸟展企业哪家好,揭秘自然界最震撼的鸟类奇观-振豪特种养殖 - 企业推荐官【认证】
  • SpringBoot 3 入门实战:从环境搭建到打包部署
  • AI技术空转破解:从评估指标到工程落地的实践指南
  • 工业与AI融合应用 | 7大核心用例落地:AI如何破解半导体研发周期长、良率低难题
  • Adobe-GenP终极指南:如何快速激活Adobe CC 2019-2023全系列软件
  • 规则 vs 本体——这道选择题没有标准答案
  • 硬盘健康状态、温度、通电次数、写入量和序列号检查软件、win10查看硬盘序列号
  • Linux系统篇:基本指令Chapter 1:对文件的操作和认识
  • 2026年 广东塑料外壳定制供应商实用选购指南 - 卓企推荐
  • 嵌入式事件驱动架构实战:从while(1)轮询到事件队列
  • 第五条
  • 2026年07月广东高精度快速模具产业格局与制造能力分析 - 卓企推荐
  • Nintendo Switch游戏安装终极指南:3种方法让你告别安装烦恼
  • SpringBoot3集成Quartz:从入门到实战
  • HybridSim:用于毫米波人体感知的物理-学习混合数字孪生
  • 本体语义平台与主数据管理的四种核心差异
  • STM32H723 FreeRTOS LAN8742
  • 2026中古风白蜡木/宋式黑胡桃家具厂家推荐:中山市三乡镇木之轩家具厂新中式实木好物盘点 - 栗子测评
  • 2026年AI核心技能:五大方向与实战指南
  • 2026年广东设备外壳有实力的厂家推荐:精密钣金与机箱机柜壳体供应厂商 - 卓企推荐
  • 2026年 广东快速模具厂家推荐:精密注塑/压铸/硅胶模具开发,高时效与品质口碑榜单 - 卓企推荐
  • 5个技巧让WindowsCleaner释放30%系统潜能,告别C盘爆红噩梦
  • 张贴小广告检测数据集VOC+YOLO格式1725张1类别