所以我有一个从script B调用特定协程的script A。script B有6个gameobjects,所以在一个循环中调用了6个不同的协程。
像这样的东西
foreach (Transform child in allChildren)
{
if (child.gameObject.GetComponent<B>() != null)
{
child.gameObject.GetComponent<B>().CallCoroutine();
}
}coroutines会运行一段时间。所有6个gameobjects的coroutine同时结束。我想在这些coroutines结束后将事件发送回script A一次。但如果我从script B发送一个事件,该事件将被触发6次。解决此问题的最佳方法是什么?
发布于 2020-08-17 23:30:14
要做到这一点,一种方法是将一个Action传递给协程,以便它在完成时调用,然后在该Action中,递减所有Action共有的计数器,如果该计数器达到零,则调用您希望调用的事件:
// B.cs
void CallCoroutine(Action callback)
{
StartCoroutine(MyCoroutine(arg1, arg2, arg3, callback));
}
IEnumerator MyCoroutine(int a, float b, string c, Action callback)
{
// ... coroutine logic here
callback();
}// A.cs
int counter = 6;
Action callback = delegate()
{
if (--counter == 0)
{
LastCoroutineCompleteEvent();
}
};
foreach (Transform child in allChildren)
{
B childB = child.gameObject.GetComponent<B>();
if (childB != null)
{
childB.CallCoroutine(callback);
}
}如果协程的数量是可变的,那么可以计算调用CallCoroutine的次数,并相应地设置counter的起始值。为了安全起见,您可能希望在调用CallCoroutine之前完成counter的起始值的设置。所以,就像这样:
// A.cs
int counter;
Action callback = delegate()
{
if (--counter == 0)
{
LastCoroutineCompleteEvent();
}
};
List<B> childBs
foreach (Transform child in allChildren)
{
B childB = child.gameObject.GetComponent<B>();
if (childB != null)
{
childBs.Add(childB);
}
}
counter = childBs.Count;
foreach (B childB in childBs)
{
childB.CallCoroutine(callback);
}发布于 2020-08-17 23:41:10
您可以让Script A等待所有协程完成,然后调用事件。它看起来像这样:
IEnumerator WaitForChildren() {
List<Coroutine> running = new List<Coroutine>();
foreach (Transform child in allChildren) {
if (child.gameObject.GetComponent<B>() != null) {
running.Add(child.gameObject.GetComponent<B>().CallCoroutine());
}
}
foreach (var coroutine in running) {
yield return coroutine;
}
ChildrenFinishedEvent();
}您需要让CallCoroutine()返回由StartCoroutine()返回的协程对象。
发布于 2020-08-17 23:26:55
你可以给你的CallCoroutine函数一个bool类型的参数,它决定事件是否应该被触发。
foreach (Transform child in allChildren)
{
bool triggerOnce = true;
if (child.gameObject.GetComponent<B>() != null)
{
child.gameObject.GetComponent<B>().CallCoroutine(triggerOnce);
if(triggerOnce) { triggerOnce = false; }
}
}https://stackoverflow.com/questions/63453651
复制相似问题