Unity/C# : 如何在另一个函数执行完后执行一个函数?
Unity/C# : How to execute a function after another function has finished its execution?
我一直在尝试为我正在进行的项目构建 "event system"。以下是我的做法:我根据一个 gameObject 和我需要从该 gameObject 执行的函数填充一个列表。然后,当 "event" 被触发时(在本例中,当玩家踏入触发对撞机时)我只是遍历列表并调用其中的函数。
问题在于列表中的每个函数都会同时执行。这在某些情况下工作正常,但如果我想创建一个更具电影效果的事件,我需要能够在前一个函数完成执行后执行一个函数。遗憾的是我不知道该怎么做。
我一直在阅读 Unity 和 C# 的大量关于协程和委托的文档,但我似乎无法全神贯注地思考所有这些事情并找到一种在代码上实现它们的方法。所以我需要你的帮助:我怎样才能做到这一点?
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 时避免协程。 (协程高级 。)
3) "I need to wait until the previous function has ended before executing the following one"
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;
如果您有 "stack" 每帧要执行的操作,只需执行此操作
void Update()
{
if (newItem = yourStack.Pop())
newItem();
}
如果您有 "stack" 件事情想做 等待每件事情完成,
void Start()
{
StartCoroutine(YourStackLoop());
}
private IEnumerator stackLoop()
{
while(true)
{
if (newItem = yourStack.Pop())
yield return StartCoroutine(newItem());
else
yield return new;
}
}
请注意,Update 和协程本质上是同一件事,阅读并研究这个。
注意 在示例中,使用您自己常用的 Push/Pop(或 FIFO,或任何您想要的)。不熟悉的可以在这里搜索很多QA
我一直在尝试为我正在进行的项目构建 "event system"。以下是我的做法:我根据一个 gameObject 和我需要从该 gameObject 执行的函数填充一个列表。然后,当 "event" 被触发时(在本例中,当玩家踏入触发对撞机时)我只是遍历列表并调用其中的函数。
问题在于列表中的每个函数都会同时执行。这在某些情况下工作正常,但如果我想创建一个更具电影效果的事件,我需要能够在前一个函数完成执行后执行一个函数。遗憾的是我不知道该怎么做。
我一直在阅读 Unity 和 C# 的大量关于协程和委托的文档,但我似乎无法全神贯注地思考所有这些事情并找到一种在代码上实现它们的方法。所以我需要你的帮助:我怎样才能做到这一点?
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 时避免协程。 (协程高级
3) "I need to wait until the previous function has ended before executing the following one"
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;
如果您有 "stack" 每帧要执行的操作,只需执行此操作
void Update()
{
if (newItem = yourStack.Pop())
newItem();
}
如果您有 "stack" 件事情想做 等待每件事情完成,
void Start()
{
StartCoroutine(YourStackLoop());
}
private IEnumerator stackLoop()
{
while(true)
{
if (newItem = yourStack.Pop())
yield return StartCoroutine(newItem());
else
yield return new;
}
}
请注意,Update 和协程本质上是同一件事,阅读并研究这个。
注意 在示例中,使用您自己常用的 Push/Pop(或 FIFO,或任何您想要的)。不熟悉的可以在这里搜索很多QA