Unity co例程(CR)是一种入门级的、有时是危险的工作形式,它在
主统一线程
. 它们对于本质上是逻辑的
lerp
跨越一系列框架,如
衰落,5秒后引爆我的宇宙飞船
或
推迟驾驶舱显示更新
.
CR在主线程上被分割和多路复用,因此游戏中最慢的部分将是单帧中时间需求最大的CR。在一次
yield
每帧都会减慢游戏速度,尤其是
输入/输出操作
.
备选方案-Unity作业
相反,考虑使用Unity
'IJob'
它允许在工作线程上执行操作,从而释放Unity线程来做它最擅长的事情
输入/输出操作不长
.
统一性:
使用IJob调度与其他作业和主线程并行运行的单个作业。调度作业时,将在工作线程上调用作业的Execute方法。
More...
现在,浪费一个可能花费一生等待I/O完成的整个线程可以说是浪费了一个非常好的线程,但这肯定比阻塞主线程要好。
协同路由。。。他们是龙
我之前提到过
“危险”
关于CRs,原因有三个方面:
-
在每秒调用多次的方法中触发CR时,例如
Update()
确保你
充分防护
这个
StartCoroutine()
否则,您最终可能会遇到无数的内存不足的情况。这种情况在堆栈溢出时很常见
-
不要错误地认为它们是某种工作线程或其他不会减慢主线程速度的魔法
-
在许多方面,CRs就像
DoEvents
,
Application.DoEvents
在里面
Visual Basic
和
.净额
分别导致了一起严重的
重新进入
(就像在多线程应用程序中一样,状态混乱且不可预测
没有螺纹
)
还有整个
团结促进了对
IEnumerator
和
产量
?
辩论
我的另一个建议是,如果您需要一些lerped或延迟的内容,并且没有进行I/O,请考虑创建一个类并使用
Time
.
例如
in my flight sim
,我只想每100ms左右更新一次驾驶舱显示。为此,我定义了
Delay
类别:
public class Delay
{
private float _lastInterval;
/// <summary>
/// The timeout in seconds
/// </summary>
/// <param name="timeout"></param>
private Delay(float timeout)
{
Timeout = timeout;
_lastInterval = Time.time;
}
public float Timeout { get; }
public bool IsTimedOut => Time.time> _lastInterval + Timeout;
public void Reset()
{
_lastInterval = Time.time;
}
public static Delay StartNew(float delayInSeconds)
{
return new Delay(delayInSeconds);
}
}
.
.
.
private void Update()
{
if (!_delay.IsTimedOut)
{
return;
}
// Do something time consuming
_delay.Reset();
}