Unity协程学习心得

前言

个人总结的一些Unity协程学习心得,如有不对请在评论区指出一起学习!感谢。

在Unity编程中谈到异步逻辑,可以考虑使用协程来实现。协程(Coroutine)在Unity中的主要作用就是把一个任务暂停(挂起),并在下一帧(或之后的某一时间点)继续。常见案例有网络请求、临时计时器、资源加载、打字机特效等。需要注意的是,协程不是线程,协程是在主线程中执行的。使用协程可以不用考虑同步和锁的问题。

1、C#迭代器

官方文档:遍历集合 - C# | Microsoft Learn

在了解并使用协程之前,我们可以先扩展一下关于C#迭代器的知识,方便我们理解什么是yield

迭代器方法或 get 访问器可对集合执行自定义迭代。 迭代器方法使用 yield return 语句返回元素,每次返回一个。 到达 yield return 语句时,会记住当前在代码中的位置。 下次调用迭代器函数时,将从该位置重新开始执行。迭代器方法或 get 访问器的返回类型可以是 IEnumerable、IEnumerable<T>、IEnumerator 或 IEnumerator<T>。

在C#中,yield可以粗浅的理解为“产出”。用于实现迭代器,逐步产出序列中的元素

案例:写一个返回数字的迭代器方法

void Start()
{
    var numbers = GetNumbers();
    while (numbers.MoveNext())
    {
        Debug.Log($"t_Coroutine {numbers.Current}");
    }
}

IEnumerator GetNumbers()
{
    yield return 0;
    yield return 1;
    yield return 200;
}

 输出:

但是在Unity中,我们只用到了IEnumerator来创建协程方法。因此,我着重介绍一下IEnumerator接口。

1.1 IEnumerator

public interface IEnumerator
{
    object Current
    {
        get;
    }

    bool MoveNext();

    void Reset();
}

可以看到其实迭代器内部很简单。

Current是当前迭代器指向的对象;MoveNext()是移动指针指向下一个对象,如果是最后一个对象则返回false;Reset()是重置为最初状态。

2、协程基本语法

2.1 写一个简单的协程

协程开始时,会顺序执行yield return null;之前的代码,遇到yield return 会被挂起(暂停),等待指定时间后,从被挂起的地方继续往下执行。

using System.Collections;
using UnityEngine;

public class CoroutineExample : MonoBehaviour
{
    void Start()
    {
        StartCoroutine(MyCoroutine());
    }

    IEnumerator MyCoroutine()
    {
        // 开启协程就会执行的逻辑
        Debug.Log("t_Coroutine Start Coroutine");
        yield return null;  //在这里被暂停,暂停1帧
        //挂起并恢复之后的逻辑
        Debug.Log("t_Coroutine Wait One Frame After");
        yield return new WaitForSeconds(2); //在这里被暂停,暂停2秒
        Debug.Log("t_Coroutine Wait Two Seconds After");
        //协程结束
    }
}

输出:

 

2.2 yield return的不同用法

2.2.1 yield return null 与 yield return 1

在Unity协程中,yield return null; 和 yield return 1; 实际上是等效的,二者都会暂停协程的执行并在下一帧继续执行。即等待一帧

之所以等效,是因为yield return会返回一个值给Unity的协程调度器,这个值用于决定协程何时继续。null和任意整数(例如1)都会导致协程在下一帧恢复执行。

2.2.2 yield break

立即停止协程

案例:可以看到Break After并没有被打印出来,在此之前协程就停止了

using System.Collections;
using UnityEngine;

public class CoroutineExample : MonoBehaviour
{
    void Start()
    {
        StartCoroutine(MyCoroutineBreak());
    }

    IEnumerator MyCoroutineBreak()
    {
        Debug.Log("t_Coroutine Start MyCoroutineBreak");
        yield return null;  //在这里被暂停,暂停1帧
        Debug.Log("t_Coroutine Wait Two Seconds After");
        yield break;//协程结束
        Debug.Log("t_Coroutine Break After");
    }
}

输出: 

2.2.3 yield return StartCoroutine(OtherCoroutine())

协程是可以嵌套的,可以使用yield return StartCoroutine(OtherCoroutine()),等待OtherCoroutine协程方法执行完毕后,再继续往下执行

案例:

void Start()
{
    Debug.Log("t_Coroutine Start1");
    StartCoroutine(TestCoroutine());
    Debug.Log("t_Coroutine Start2");
}

IEnumerator TestCoroutine()
{
    Debug.Log("t_Coroutine test1");
    yield return StartCoroutine(LoadCoroutine());
    Debug.Log("t_Coroutine test2");
}

IEnumerator LoadCoroutine()
{
    Debug.Log("t_Coroutine load 1");
    yield return null;
    Debug.Log("t_Coroutine load 2");
}

输出:

 

 2.2.4 其他用法

yield return new WaitForEndOfFrame();//等待帧结束

yield return new WaitForSeconds(1f);//等待1秒;

yield return WebRequest();//等待到网络请求结束返回结果的时候;

yield return new WaitUntil()//等待到结果返回为true的时候

yield return new WaitWhile()//等待到结果返回为false的时候

2.3 开启 / 停止协程

2.3.1 直接开启一个协程

无法控制暂停,直接调用协程方法开启

StartCoroutine(MyCoroutine());

2.3.2 用变量控制协程

private Coroutine myCoroutine;
myCoroutine = StartCoroutine(MyCoroutine());//开启协程
StopCoroutine(myCoroutine);//停止协程

2.3.3 用协程方法名控制协程

StartCoroutine("MyCoroutine");//开启协程
StopCoroutine("MyCoroutine");//停止协程

2.3.4 停止所有正在运行的协程

会停止该对象上所有正在运行的协程,慎用!

当一个游戏对象(GameObject)把Active设置为false,即SetActive(false),也会停止该对象上附加的协程。

调用Destroy(GameObject)时,Unity会调用OnDisable(),处理并停止协程。在这一帧结束时,会调用OnDestroy()。

StopAllCoroutines();

3、学习参考博客

官方文档:Unity - Manual: Coroutines

通俗易懂博客(建议先看这个,很好理解):Unity C#中协程/携程Coroutine简单易懂详解-CSDN博客

更进一步理解:Unity StartCoroutine - 简书

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/694374.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Java集合汇总

Java中的集合框架是Java语言的核心部分&#xff0c;提供了强大的数据结构来存储和操作对象集合。集合框架位于java.util包中&#xff0c;主要可以分为两大类&#xff1a;Collection&#xff08;单列集合&#xff09;和Map&#xff08;双列集合&#xff09;。下面是对它们的总结…

NXP i.MX8系列平台开发讲解 - 3.14 Linux 之Power Supply子系统(二)

专栏文章目录传送门&#xff1a;返回专栏目录 Hi, 我是你们的老朋友&#xff0c;主要专注于嵌入式软件开发&#xff0c;有兴趣不要忘记点击关注【码思途远】 目录 1. 前言 2. 芯片简介 2. 系统原理设计 2. 设备树相关 本文实操是基于Android11 系统下i.MX8MQ环境下&#x…

博睿数据应邀出席双态IT用户大会,分享《构建云原生时代的一体化智能可观测性》

5月31日-6月2日&#xff0c;第十二届双态IT用户大会于成都成功举行&#xff0c;此次大会由DCMG和双态IT论坛联合主办&#xff0c;聚焦“信创时代的组织级云原生能力建设”和“组织级云原生运维能力建设”两大会议主题&#xff0c;旨在推动双态IT落地与创新&#xff0c;为企业数…

LabVIEW在高校中的应用

LabVIEW 作为一款功能强大的图形化编程工具&#xff0c;在高校中有广泛的应用。它不仅用于教学实验&#xff0c;还广泛应用于科研项目和工程训练。本文将从教学、科研、实验室管理和学生技能培养等多个角度&#xff0c;详细分析LabVIEW在高校中的应用。 教学应用 课程设计 自动…

快来速领限量免费亚马逊云科技助理级架构师(SAA)和云从业者50%半价考试券

前几天在上海5/29的亚马逊云科技Summit峰会里&#xff0c;小李哥在现场分享了AWS 13张认证大满贯的心得&#xff08;图1&#xff09;&#xff0c;并且现场招募了自己的云师兄必过班(图2)。 本次必过班也为成员发放AWS SAA(助理级架构师)和云从业者(Cloud Practitioner)50%考试券…

华为防火墙配置 SSL VPN

前言 哈喽&#xff0c;我是ICT大龙。本期给大家更新一次使用华为防火墙实现SSL VPN的技术文章。 本次实验只需要用到两个软件&#xff0c;分别是ENSP和VMware&#xff0c;本次实验中的所有文件都可以在文章的末尾获取。话不多说&#xff0c;教程开始。 什么是VPN 百度百科解…

未在本地计算机上注册“Microsoft.ACE.OLEDB.12.0”提供程序。.net 读取excel的时候报错(实测有效)

1. 下载AccessDatabaseEngine.exe 下载链接 添加链接描述 2. office excel是64为的需要安装【AccessDatabaseEngine.exe】、32位的【AccessDatabaseEngine_X64.exe】 3. 我的是64为&#xff0c;跳过32位安装检测 1. 找到下载的安装包 2.输入安装包文件全称并在后面加上/pas…

C++之RTTI

1、RTTI&#xff08;runtime type information&#xff09;运行时类型信息 static_cast&#xff1a;用在编译器认可的转型 reinterpret_cast&#xff1a;用在编译器不认可的转型&#xff08;不做任何的对齐操作&#xff09; const_cast&#xff1a;去除常量属性 dynamic_ca…

Java 泛型类,泛型方法,泛型接口和通配符(用来限定类和方法的使用范围)

测试类 package Genericity;import java.util.ArrayList;public class test {public static void main(String[] args) {// 使用泛型方法添加元素ArrayList<String> list new ArrayList<>();MyToolClass.ListAdd(list,"fdsf","dsfa");System…

Triton学习笔记

b站链接&#xff1a;合集Triton 从入门到精通 文章目录 算法名词解释&#xff1a;scheduler 任务调度器model instance、inference和requestbatching 一、Triton Inference Server原理1. Overview of Trition2. Design Basics of Trition3. Auxiliary Features of Trition4. A…

C++笔试强训day42

目录 1.最大差值 2.兑换零钱 3.小红的子串 1.最大差值 链接https://www.nowcoder.com/practice/a01abbdc52ba4d5f8777fb5dae91b204?tpId182&tqId34396&rp1&ru/exam/company&qru/exam/company&sourceUrl%2Fexam%2Fcompany&difficulty2&judgeSta…

6.9总结

Vue生命周期 生命周期&#xff1a;指一个对象从创建到销毁的整个过程生命周期的八个阶段&#xff1a;每触发一个生命周期事件&#xff0c;会自动执行一个生命周期的方法&#xff08;钩子&#xff09; mounted&#xff1a;挂载完成&#xff0c;Vue初始化成功&#xff0c;HTML渲…

JAVA小案例-递归:计算n!

JAVA小案例-递归&#xff1a;计算n! 首先抛出概念&#xff0c;什么是递归&#xff1f; 说白了就是自己调用自己。 递归的结构&#xff1a; &#xff08;1&#xff09;递归头&#xff1a;就是什么时候不调用自身的方法&#xff0c;也就是递归结束的条件 &#xff08;2&#xff…

轴承接触角和受力分析

提示&#xff1a;轴承接触角和受力分析 文章目录 1&#xff0c;接触角2&#xff0c;轴承受力分析 1&#xff0c;接触角 所谓公称接触角就是指轴承在正常状态下&#xff0c; 滚动体和内圈及外圈沟道接触点的法线与轴心线的垂直平面之间的夹角。 按滚动轴承工作时所能承受载荷的…

AI大模型学习(非常详细)零基础入门到精通,收藏这一篇就够了

前言 随着人工智能技术的快速发展&#xff0c;AI大模型学习正成为一项备受关注的研究领域。为了提高模型的准确性和效率&#xff0c;研究者们需要具备深厚的数学基础和编程能力&#xff0c;并对特定领域的业务场景有深入的了解。通过不断优化模型结构和算法&#xff0c;AI大模…

Nginx部署多web进程

1、nginx介绍 Nginx是一个高性能的、开源的、跨平台的Web服务器和反向代理服务器。它是由俄罗斯的程序员Igor Sysoev开发的&#xff0c;并于2004年首次公开发布。 Nginx的特点包括&#xff1a; 高性能&#xff1a;Nginx使用事件驱动的架构&#xff0c;能够处理大量的并发连接…

GAT1399协议分析(9)--图像上传

一、官方定义 二、wirechark实例 有前面查询的基础,这个接口相对简单很多。 请求: 文本化: POST /VIID/Images HTTP/1.1 Host: 10.0.201.56:31400 User-Agent: python-requests/2.32.3 Accept-Encoding: gzip, deflate Accept: */* Connection: keep-alive content-type:…

基于睡眠声音评估睡眠质量

随着健康意识的增强&#xff0c;人们越来越关注睡眠质量。确保获得充足的高质量睡眠对于维持身体健康和心理平衡至关重要。专业的睡眠状态测量主要通过多导睡眠图&#xff08;PSG&#xff09;进行。然而&#xff0c;PSG会给受试者带来显著的身体负担&#xff0c;并且在没有专业…

Edge浏览器视频画中画可拉动进度条插件Separate Window

平时看一些视频的时候&#xff0c;一般需要编辑一些其他的东西&#xff0c;于是开启画中画&#xff0c;但是画中画没有进度条&#xff0c;需要大幅度的倒退前进得回到原视频&#xff0c;很麻烦。这里推荐插件Separate Window&#xff0c;可实现画中画进度条拉动和播放sudu的调节…

DS:堆的结构与实现

欢迎来到Harper.Lee的学习世界&#xff01;博主主页传送门&#xff1a;Harper.Lee的博客主页想要一起进步的uu可以来后台找我哦&#xff01; 一、堆的概念与结构 1.1 堆的概念 堆&#xff08;Heap&#xff09;是完全二叉树中的一种&#xff0c;分为大根堆和小根堆。 特点&#…