【发布时间】:2021-11-27 11:03:36
【问题描述】:
【代码】
private void Start()
{
StartCoroutine(A1());
StartCoroutine(A2());
StartCoroutine(A3());
}
IEnumerator A1()
{
while (true)
{
print("A1");
yield return new WaitForSeconds(3);
}
}
IEnumerator A2()
{
while (true)
{
print("A2");
yield return new WaitForSeconds(3);
}
}
IEnumerator A3()
{
while (true)
{
print("A3");
yield return new WaitForSeconds(3);
}
}
【输出】
A1
A2
A3
A1
A2
A3
A1
A2
A3
A1
A2
A3
...
【我的问题】
A1(),A2(),A3() 总是按顺序运行。
确定吗?
“yield return null”、“yield return WaitForSeconds”和其他“yield return X”是一样的吗?
为什么我有这个问题?
在 Unity 的Order of execution for event functions 中,不同的“收益回报 X”发生在不同的时间。
然后我想知道,如果几个相同类型的“yield return X”(在同一个 MonoBehaviour 中)总是按顺序发生。
更新1
1.1
@joreldraw 在评论中说
将 A1 更改为 20 秒,将 A2 更改为 10,然后重试 :)
这是代码和输出。
【代码】
private void Start()
{
StartCoroutine(A1());
StartCoroutine(A2());
}
IEnumerator A1()
{
while (true)
{
print($"A1,frame:{Time.frameCount},time:{Time.time}");
yield return new WaitForSeconds(10f);
}
}
IEnumerator A2()
{
while (true)
{
print($"A2,frame:{Time.frameCount},time:{Time.time}");
yield return new WaitForSeconds(20f);
}
}
【输出】
A1,帧:3187,时间:10.00139
A2,帧数:6495,时间:20.0001
A1,帧:6496,时间:20.00392
A1,帧:9686,时间:30.00965
A2,帧:13093,时间:40.0004
A1,帧:13095,时间:40.01266
A1,帧:16445,时间:50.01303
A2,帧数:19695,时间:60.00157
A1,帧:19699,时间:60.01489
1.2
我想知道的是,它们在同一帧时是否保持有序。
所以我把时间改成 0.01s 和 0.02s 。
【输出】
A1,帧:3,时间:0.3533334
A2,帧:3,时间:0.3533334
...
A2,帧:10,时间:0.4100522
A1,帧:11,时间:0.4132612
A1,帧:15,时间:0.4247341
...
A1,帧:38,时间:0.4942196
A2,帧:38,时间:0.4942196
...
A2,帧数:52,时间:0.5754243
A1,帧:52,时间:0.5754243
A1,帧:54,时间:0.5914614
...
1.3
很难确定协程是否保持有序。所以我修改了代码,只在协程在同一帧运行时才打印。
HashSet<int> a1Set = new HashSet<int>();
HashSet<int> a2Set = new HashSet<int>();
private void Start()
{
StartCoroutine(A1());
StartCoroutine(A2());
}
IEnumerator A1()
{
while (true)
{
a1Set.Add(Time.frameCount);
if (a2Set.Contains(Time.frameCount))
{
print($"First 2, Then 1, frame:{Time.frameCount}");
}
yield return new WaitForSeconds(0.01f);
}
}
IEnumerator A2()
{
while (true)
{
a2Set.Add(Time.frameCount);
if (a1Set.Contains(Time.frameCount))
{
print($"First 1, Then 2, frame:{Time.frameCount}");
}
yield return new WaitForSeconds(0.02f);
}
}
【输出】
前 1,后 2,帧:3
先1,后2,帧:4
先2,后1,帧:9
先2,后1,帧:16
先2,后1,帧:22
先2,后1,帧:28
先1,后2,帧:76
先1,后2,帧:135
先1,后2,帧:179
先2,后1,帧:186
先1,后2,帧:222
【问题讨论】:
-
将您的 A1 更改为 20 秒,A2 更改为 10,然后再试一次 :)
-
@joreldraw 为什么?我不认为这是这里的问题^^
-
您的实际用例是什么?为什么不简单地使用一个每 3 秒按顺序执行 A0-4 的例程?
-
@derHugo 这里没有用例。我想到了这个问题^^(所以这可能是一个毫无意义的问题)。我知道 Unity 的“事件执行顺序”,不同类型的“收益回报 X”发生在不同的时间。然后我想知道,如果几个相同类型的“yield return X”(在同一个 MonoBehaviour 中)按顺序发生。
-
@joreldraw 我根据你的评论做了一些测试。他们已被添加到帖子中。