深入探讨Unity协程及其使用

article/2025/11/1 5:29:17

深入探讨Unity协程及其使用

协程

协程在Unity中是个很重要的东东,相信很多人都使用过,它能够非常方便的进行异步等待操作,可以说,用好协程,可以使你的代码更加优雅,然而,如果用不好,代码就会有变成翔的可能,甚至已经变成了翔,你自己居然还不知道。那么,我们就来好好聊聊协程吧。

协程的本质

协程并不是Unity创造的,它本来就存在于C#。协程的本质是迭代器,通过调用MoveNext(),直到迭代结束。
通过下面的代码,可以清晰的看到他的工作原理:

static IEnumerator<int> MyCoroutine()
{yield return 0;yield return 1;for( int i = 2; i < 10; ++ i )yield return i;
}static void Main(string[] args)
{var mc = MyCoroutine();while( mc.MoveNext()){Console.WriteLine( mc.Current );}Console.ReadKey();
}

在Unity的游戏循环中,每次循环或者说每帧都会去调用MoveNext(),于是看起来,协程“并行”了。然而,协程并不是线程,它本质并不是并发的。

协程带来的问题

请看下面的例子:
public float speed = 0.5f / 1f;
CanvasGroup group;private void Start()
{group = GetComponenet<CanvasGroup>();
}public void Show()
{StartCoroutine(_show());
}public void Hide()
{StartCoroutine(_hide());
}private IEnumerator _show()
{while( group.Alpha < 0.999 )group.Alpha += speed * Time.deltaTime;group.Alpha = 1;
}private IEnumerator _hide()
{while( group.Alpha > 0.001 )group.Alpha -= speed * Time.deltaTime;group.Alpha = 0;
}

上面的例子中,实现了一个UI的渐隐和渐现功能,一般情况下,它能很好的工作。当你调用了Show(),他会渐现,当你调用了Hide(),他会渐隐。然而,它潜在的问题是,如果你调用了Show(),渐现到一半时(_show协程未结束),接着调用Hide(),那么两个协程将同时运行,一个负责增加group.Alpha,另一个负责减少group.Alpha,导致group.Alpha始终不会高于0.999,也始终不会低于0.001,界面就卡在那里了。
那么为了保证每次只有一个协程在运行,你可能会这么改:

public void Show()
{StopAllCoroutine();StartCoroutine(_show());
}public void Hide()
{StopAllCoroutine();StartCoroutine(_hide());
}

虽然通过加一个StopAllCoroutine()能解决上面的问题,但最起码,它已经不怎么“优雅”了。更优雅的实现同样功能,应该考虑使用状态机,而不是协程。

再来看一个例子:

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

这是unity官方在B站发布的视频,他的大意是:第一,协程是语法糖,他本质上是一个状态机,加上一堆goto语句。第二,也是最重要的,不要让一个协程永远不退出,就是不要有上图例子中的while(true)这样的协程,他强烈不建议这么用,因为这样可能会有内存问题。有兴趣的可以去看看原视频——“豆知识 匿名类”。

到底应该什么时候用协程

使用协程应该满足“FIRE AND FORGET”原则,即“点火后忘记”原则。就是说,只需要发起它,而不用管它后续的情况(不需要时刻记得它),就可以使用协程。比如说,发起一个资源下载,然后等他出来结果。

另外,协程只工作在主线程,他只是循环的被调用,本身并不能解决并发的问题,所以,如果你想要并发,请使用多线程。

白猫,黑猫,抓到老鼠就是好猫,总之,没有绝对的好于坏,具体需求要具体分析,协程也好,线程也罢,各有各的优缺点,只要能实现功能需求,达到性能要求,就是好的,但这就需要我们深入的去理解功能点,分析需求逻辑。


http://chatgpt.dhexx.cn/article/rmxKLyE9.shtml

相关文章

Unity 协程、模拟协程

理解协程 IEnumeratoryield 强大的迭代器 IEnumerator 就是一个函数容器 里面保存了一个一个的函数 IEnumator会依次执行每个函数 而每个函数都有一个返回值 保存在IEnumator.Currect里面 看下面这个例子 IEnuermator start_Coroutine(){Debug.Log("HellWord")…

unity 协程特点

协程 一. Unity中使用协程1. 什么是协程2. 如何使用3. 协程的应用场景创建补间动画打字机效果异步加载资源 4. 注意事项 二. Unity协程的底层原理1. 协程本体&#xff1a;C#的迭代器函数2. 协程调度&#xff1a;MonoBehaviour生命周期中实现3. Unity协程的架构 三. 扩展Unity的…

Unity协程深入及实现

Unity协程深入 文章目录 Unity协程深入Unity协程简介Unity协程的用法协程的原理协程的缺陷自己实现协程参考 Unity协程简介 Unity中的协程能够允许我们将一个任务分散到多个帧中。注意&#xff1a;协程&#xff08;协同执行&#xff09;和多线程有本质区别。 协程不是线程&…

unity 协程

首先声明&#xff1a;协程不是线程&#xff0c;协程在主线程中运行&#xff0c;而线程是单独开辟线程 以下是u3d关于协程的调用机制的解释&#xff1a; “在Unity3D中&#xff0c;使用MonoBehaviour.StartCoroutine方法即可开启一个协同程序&#xff0c;也就是说该方法必须在…

【Unity】Unity协程(Coroutine)的原理与应用

文章目录 前言一、什么是协程二、应用场景1.异步加载资源2.将一个复杂程序分帧执行3.定时器 三、协程的使用注意事项 四、Unity协程的底层原理1. 协程本体&#xff1a;C#的迭代器函数2. 协程调度&#xff1a;MonoBehaviour生命周期中实现 五、参考资料 前言 本文是作者在学习U…

Unity-协程详解

1. 简介 unity的**协程&#xff08;Coroutine&#xff09;**只是在c#的基础上做了一层封装&#xff0c;其实yield是C#的关键字。 unity协程是一个能够暂停协程执行&#xff0c;暂停后立即返回主函数&#xff0c;执行主函数剩余的部分&#xff0c;直到中断指令完成后&#xff…

Unity 协程(Coroutine)原理与用法详解

前言&#xff1a; 协程在Unity中是一个很重要的概念&#xff0c;我们知道&#xff0c;在使用Unity进行游戏开发时&#xff0c;一般&#xff08;注意是一般&#xff09;不考虑多线程&#xff0c;那么如何处理一些在主任务之外的需求呢&#xff0c;Unity给我们提供了协程这种方式…

linux的用户管理

1.linux的用户管理 linux的用户管理和组管理&#xff0c; 每个用户都必须要有一个且仅有一个初始组&#xff0c;可以有多个附加组&#xff0c;使用useradd命令创建用户时&#xff0c;如果没有指定初始组&#xff0c;系统默认会创建一个于其同名的组。 用户和组信息保存在4个文…

Linux用户管理练习

Linux下用户分为3类&#xff1a;超级用户&#xff08;root&#xff09;、系统用户、普通用户。 超级用户的用户名为root&#xff0c;它具有一切操作权力&#xff0c;因此为安全起见&#xff0c;建议不要轻易的在root账户下面对文件进行操作。在Linux操作系统的字符界面&#xf…

Linux用户管理工具

Linux用户管理工具 1. 用户 1.1创建用户 useradd -m username该命令为用户创建相应的帐号和用户目录/home/username&#xff1b; passwd username该命令为用户设置密码 1.2 删除用户 userdel -r username不带选项使用 userdel&#xff0c;只会删除用户。用户的家目录将…

Linux上的用户管理

Linux是一个多用户多任务的系统&#xff0c;任何人想要访问系统资源&#xff0c;必须通过登录账号来访问系统资源 添加用户 useradd&#xff1a;添加用户的命令&#xff08;root才能添加用户&#xff09; 用法&#xff1a;useradd 用户名 例&#xff1a;useradd water 就创建…

实现Linux用户管理

1.添加用户组&#xff1a;groupadd 用户组名称 2.创建用户 &#xff08;一&#xff09;仅创建用户&#xff1a;useradd 用户名 &#xff08;二&#xff09;指定用户所属的用户组&#xff1a; useradd -g 用户组 3.设置用户密码 &#xff08;一&#xff09;passwd 普通用户名 …

linux用户管理及操作指令

1、首先了解下linux是一个多用户多任务的操作系统。任何一个需要使用资源的用户都需要从linux系统中分配一个用户角色&#xff0c;比如&#xff1a;root、user、、然后使用对应账号进入系统。一个root用户下面能创建多个用户&#xff0c;每个用户下面对应一个目录 2、添加用户…

浅谈Linux用户管理

Linux用户管理 准备工作&#xff1a; 在管理用户时&#xff0c;执行命令后是无法看到效果的&#xff0c;最开始我们可以通过系统监视命令来对用户信息进行监控&#xff0c;使操作步骤可视。 watch -n 1 tail -n3 /etc/passwd;ls -l /home/ 注释&#xff1a; 部分含义watch …

Linux用户管理(Centos7)

用户管理 用户命令 添加登录用户&#xff1a; 例&#xff1a;添加一个名为harry的用户&#xff0c;并使用bash作为登录的shell [rootaws ~]# useradd harry [rootaws ~]# tail -1 /etc/passwd harry:x:1002:1002::/home/harry:/bin/bashharry:x:1001:1001::/home/harry:/bin/…

Linux用户管理机制

Linux系统中的用户管理涉及用户账号文件 /etc/passwd、用户密码文件 /etc/shadow、用户组文件 /etc/group。 一、用户账号文件 /etc/passwd 该文件为纯文本文件&#xff0c;可以使用cat、head等命令查看。该文件记录了每个用户的必要信息&#xff0c;文件中的每一行对应一个用…

【Linux用户管理】

目录 前言 用户管理的基本命令 前言 Linux是一个多用户、多任务的操作系统&#xff0c;具有很好的稳定性与安全性&#xff0c;在linux系统中&#xff0c;root用户具有最高的权限&#xff0c;但该身份不当使用会带来一些不必要的麻烦和潜在的风险&#xff0c;故需要添加一些普通…

Linux之用户管理

一、用户的增删改查 1.增加用户 语法&#xff1a;useradd用户名 在终端输入 useradd 用户名 在linux系统home文件夹下面会出现新建用户的文件夹 2.修改密码 语法&#xff1a;passwd用户名 输入passwd 用户名&#xff0c;输入新的密码之后就可以使用新建的用户登录 3.删除用…

Linux用户管理-相关命令及配置文件-超详细-概念详解-初学全

前言 Linux系统作为多用户多任务的操作系统&#xff0c;可以在同一时间内允许多个用户登录、操作及配置计算机&#xff0c;随着需求的增加&#xff0c;用户的增加&#xff0c;我们也就需要对用户进行管理&#xff0c;以至于更有效地开展项目&#xff0c;改善工作&#xff0c;更…