Unity/C# : How to execute a function after another function has finished its execution?

时间:2016-03-04 18:13:59

标签: events unity3d delegates yield coroutine

I've been trying to build a "event system" for a project that I'm working on . Here is how I'm doing it : I populate a list with reference to a gameObject and the functions that I need to execute from that gameObject . Then , when the "event" is triggered (in this case , when the player steps into a trigger collider) I just loop over the list and Invoke the functions inside it.

The problem with this is that every single function inside the list gets executed at the same time. This works fine in some cases but if I want to create a more cinematic event I need to have the ability to execute a function after the previous one has finished it's execution .Sadly I have no idea how to do that.

I've been reading a lot of the documentation of both Unity and C# about coroutines and delegates but I can't seem to wrap my head around all those things and find a way to do implement them on code .So I need your help with that :How can I achieve this?

1 个答案:

答案 0 :(得分:4)

1)使用Invoke

private void BeginRace()
{
Invoke("WaveFlag", 0.5f);
Invoke("Beeps", 1.5f);
Invoke("CrowdBeginsCheer", 2f);
Invoke("CarsStartMoving", 2.2f);
}

2)使用协程

private void BeginRace()
{
StartCoroutine(RaceSequence());
}

private IEnumerator RaceSequence()
{
yield return new WaitForSeconds(.5f);
WaveFlag();
yield return new WaitForSeconds(1f);
Beeps();
yield return new WaitForSeconds(.5f);
CrowBeginsCheer();
yield return new WaitForSeconds(.2f);
CarsStartMoving();
}

您必须掌握协同程序和Invoke。一定要尽可能简单地使用Invoke。当你刚刚学习Unity时,请避免使用协同程序。 (关于协同程序的高级essay。)

3)“我需要等到上一个功能结束后再执行下一个”

a)每个功能必须是IEnumerator

private IEnumerator ExplodeCar()
 {
 ..
 }

private IEnumerator CrowdReaction()
 {
 ..
 }

private IEnumerator WinningCelebration()
 {
 ..
 }

b)逐个称呼,等待每个人完成

private void Sequence()
 {
 StartCoroutine(Seq())
 }

private IEnumerator Seq()
 {
 yield return StartCoroutine(ExplodeCar());
 yield return StartCoroutine(CrowdReaction());
 yield return StartCoroutine(WinningCelebration());
 }

脚注

如果您想等到下一帧,请使用:

yield return null;

如果你想要每帧都有“堆叠”的东西,就这样做吧

void Update()
  {
  if (newItem = yourStack.Pop())
    newItem();
  }

如果您有“堆叠”的事情等待每个事情完成

void Start()
 {
 StartCoroutine(YourStackLoop());
 }
private IEnumerator stackLoop()
  {
  while(true)
    {
    if (newItem = yourStack.Pop())
      yield return StartCoroutine(newItem());
    else
      yield return new;
    }
  }

请注意,更新和协程基本上是相同的,阅读和研究。

示例中的

注意,使用您自己常用的Push / Pop(或FIFO,或任何您想要的)。如果不熟悉,请在此处搜索许多质量保证。