Unity2D游戏开发-延迟执行的方式

使用协程(Coroutines)

示例

协程可以将一个方法转换为多个帧执行,yield return可以将其拆分成多段执行。

使用yield return可以将一个方法拆分成多段执行,非常适合用于过场动画、顺序执行多个过程等。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
private void ShowShootAnimi()
{
_animator.SetBool(AnimUtils.IsShoot, true);
}

private IEnumerator HideShootAnimi()
{
yield return new WaitForSeconds(1);
// 这里的代码会在1秒后执行
_animator.SetBool(AnimUtils.IsShoot, false);
}

public void Shoot() {
StartCoroutine(HideShootAnimi());
}

yield return

在 Unity 中,yield return 关键字用于实现协程,它可以将一个方法拆分成多段执行。

yield return 的常见用法有:

暂停一帧

让协程暂停一帧后继续执行。

1
yield return null;

暂停固定帧间隔

固定帧更新(Fixed Update) 的频率默认是 0.02 秒一次,不受场景渲染性能影响。

跟上面的区别在于,如果游戏是60帧,如果电脑性能差的话,可能只能达到30帧,那么上面的方法的延迟就是1/30,而给方法不受影响依旧是1/60。

1
yield return new WaitForFixedUpdate();

暂停数秒

让协程暂停指定秒数后继续执行。

1
yield return new WaitForSeconds(2f);

暂停到指定时间

让协程暂停到指定时间后继续执行。

1
yield return new WaitUntil(() => player.IsDead);

或者

1
yield return new WaitUntil(() => Time.time >= waitTime);

启动一个协程

启动一个协程作为子程序运行,子程序运行后在继续。

1
yield return StartCoroutine(LoadScene());

多个协程并行执行

1
2
3
4
IEnumerator Main() {
yield return StartCoroutine(Coroutine1());
yield return StartCoroutine(Coroutine2());
}

Coroutine1 和 Coroutine2 两个协程会并行执行,而 Main 协程处于暂停状态。

当 Coroutine1 和 Coroutine2 都执行完毕后,Main 协程才会继续往下执行。

网络请求后运行

yield return www:
用于异步网络请求,请求完成后继续执行。

1
2
WWW www = new WWW("https://www.psvmc.cn");
yield return www;

立即结束协程的执行

1
yield break;

总结起来,yield return 的作用是将协程分割成多个部分,控制协程的执行顺序和节奏。
使用它可以实现很多有用的效果,如时间延迟、等待资源加载等

使用Invoke方法

Invoke可以在指定的时间后调用一个方法。

Invoke方法使用简单,通过一个方法就可以轻松实现延迟调用,所以也很常用。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
private void ShowShootAnimi()
{
_animator.SetBool(AnimUtils.IsShoot, true);
}

private void HideShootAnimi()
{
_animator.SetBool(AnimUtils.IsShoot, false);
}

public void Shoot()
{
ShowShootAnimi();
Invoke(nameof(HideShootAnimi), 1);
}

使用延迟帧计时器

通过Time.deltaTime计时,当累积时间超过延迟时间时执行代码。

如果要精确控制延迟的时机,帧计时器会更灵活。

1
2
3
4
5
6
7
8
9
10
11
float elapsedTime = 0; 

void Update() {
elapsedTime += Time.deltaTime;

if(elapsedTime >= 2) {
// 2秒后执行的代码

elapsedTime = 0;
}
}

使用线程睡眠

使用Thread.Sleep可以使当前线程睡眠指定时间。

线程睡眠会 Block 当前线程,通常只在需要完全阻塞执行流程的时候使用。

一般不推荐使用。

1
2
3
4
void DelayedFunction() {
Thread.Sleep(2000);
// 线程睡眠2秒后继续执行
}