首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Unity3D:从多个子游戏对象中调用一次事件

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

Stack Overflow用户
提问于 2020-08-17 23:09:42
回答 3查看 55关注 0票数 0

所以我有一个从script B调用特定协程的script Ascript B有6个gameobjects,所以在一个循环中调用了6个不同的协程。

像这样的东西

代码语言:javascript
复制
foreach (Transform child in allChildren)
       {
           
           if (child.gameObject.GetComponent<B>() != null)
           {
               child.gameObject.GetComponent<B>().CallCoroutine();
           }

       }

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

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2020-08-17 23:30:14

要做到这一点,一种方法是将一个Action传递给协程,以便它在完成时调用,然后在该Action中,递减所有Action共有的计数器,如果该计数器达到零,则调用您希望调用的事件:

代码语言:javascript
复制
// 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();
}
代码语言:javascript
复制
// 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的起始值的设置。所以,就像这样:

代码语言:javascript
复制
// 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);
}
票数 1
EN

Stack Overflow用户

发布于 2020-08-17 23:41:10

您可以让Script A等待所有协程完成,然后调用事件。它看起来像这样:

代码语言:javascript
复制
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()返回的协程对象。

票数 2
EN

Stack Overflow用户

发布于 2020-08-17 23:26:55

你可以给你的CallCoroutine函数一个bool类型的参数,它决定事件是否应该被触发。

代码语言:javascript
复制
foreach (Transform child in allChildren)
{
   bool triggerOnce = true;
   if (child.gameObject.GetComponent<B>() != null)
   {
        child.gameObject.GetComponent<B>().CallCoroutine(triggerOnce);
        if(triggerOnce) { triggerOnce = false; }

   }

}
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/63453651

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档