一、Unity 协程与线程的本质区别
我用最清晰的表格总结:
| 特性 | Unity 协程 | 线程(Thread / Task) |
|---|---|---|
| 是否并行执行 | ❌ 不并行(主线程调度) | ✔ 真正并行 |
| 是否多核利用 | ❌ 不利用 | ✔ 利用多核 |
| 是否可访问 Unity API | ✔ 可以 | ❌ 不可以 |
| 是否安全修改 GameObject | ✔ 可以 | ❌ 不可以(必须丢回主线程) |
| 是否适合耗时计算 | ❌ 不适合 | ✔ 合适 |
| 是否适合执行流程脚本 | ✔ 最适合 | 一般 |
| 调度者 | Unity 引擎 | 操作系统 |
| 性能成本 | 极低 | 较高 |
协程式unity级别,让主线程的逻辑按照时间或状态分步执行。
线程是操作系统级别,做真正的多核计算,不能操作Unity对象。
二、协程的应用场景
1. 分帧执行,比如生成一万个物体,每帧生成1000个。
2. 等待某个状态结束后做什么事。比如血量小于0死亡:
yield return new WaitUntil(() => hp <= 0);
3.在循环中等待,比如每一秒怎么样。
while (true)
{
DoCheck();
yield return new WaitForSeconds(1);
}
三、协程能做异步的原因
协程可以暂停。
协程由Unity调度,运行在主线程,不是多线程。
举例,比如逻辑A和逻辑B,A执行完30%暂停,然后执行逻辑B。
B执行完百分之40暂停,然后执行逻辑A。
A执行到百分之50暂停,然后执行逻辑B。
这样看,A和B是交替执行,造成了异步的效果。
四、协程的底层实现原理
我的总结:
1. IEnumerator接口的样子
public interface IEnumerator
{
object Current { get; }
bool MoveNext();
void Reset();
}
Current 是集合中当前迭代位置的元素。
MoveNext是移动到集合的下个位置,成功推进返回true,到达末尾返回false。
Reset()就是恢复到初始位置,为-1。
2. yield的作用
文章的说法是“利用yield关键字,只需要下面简单的几行代码,就可以快速定义一个迭代器”
// 由迭代器函数定义的迭代器
IEnumerator Test()
{
yield return 1;
Debug.Log("Surprise");
yield return 3;
yield break;
yield return 4;
}
我更直白的理解:
Test函数返回的是一个“集合“,每个yield代码都是集合中的一个元素,这个元素中包含了移动到下一个元素位置的条件,unity调用IEnumerator中的MoveNext来移动到下一个元素。
3.MoveNext方法
MoveNext是关键,unity引擎什么时候调用MoveNext,迭代器或者说一个集合就尝试往下个元素移动。
比如yield return WaitForSeconds的意思就是,如果Current是WaitForSeconds类型,那么就等到达时间之后MoveNext。
2783

被折叠的 条评论
为什么被折叠?



