Unity3D:从多个子游戏对象中调用一次事件

问题描述

因此,我有一个script A,它从script B调用特定的协程。 gameobjects中有6个script B,因此在for循环中调用了6个不同的协程。

类似这样的东西

foreach (Transform child in allChildren)
       {
           
           if (child.gameObject.GetComponent<B>() != null)
           {
               child.gameObject.GetComponent<B>().CallCoroutine();
           }

       }

coroutines运行了一段时间。所有6个coroutine的{​​{1}}同时结束。我想在这些gameobjects之后将事件发送回script A。但是,如果我从coroutines发送事件,则该事件将被触发6次。解决此问题的最佳方法是什么?

解决方法

您可以让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()返回的协程对象。

,

一种方法是将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的起始值。为了安全起见,您可能需要在调用counter之前完成设置CallCoroutine的起始值。所以,像这样:

// 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);
}
,

您可以为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; }

   }

}

相关问答

依赖报错 idea导入项目后依赖报错,解决方案:https://blog....
错误1:代码生成器依赖和mybatis依赖冲突 启动项目时报错如下...
错误1:gradle项目控制台输出为乱码 # 解决方案:https://bl...
错误还原:在查询的过程中,传入的workType为0时,该条件不起...
报错如下,gcc版本太低 ^ server.c:5346:31: 错误:‘struct...