Unity3D项目实战笔记(5):延时功能的几种实现
在我过往参与开发的系统中,涵盖了单机版系统(2005 年)、CS 系统(2010 年)以及实时系统(2015 年),这些系统都具备“延时”功能,主要用于定时调度。本博客将聚焦于实时系统中基于 Unity3D 游戏引擎的延时功能实现。
在 Unity3D 里,新建的脚本默认会继承 MonoBehaviour 类,其中的 Update 函数会由引擎自动调度。以我的电脑为例,Update 函数的调用周期约为 0.012 秒。那么,在 Unity3D 中,是否只能通过 Update 函数来实现延时功能呢?是否还有其他实现方式呢?
举个实际的例子,如何让一个界面仅显示 1 秒后再执行其他操作?比如游戏的胜利界面,只显示 1 秒后执行后续操作。答案是肯定的,下面将为大家详细介绍几种我使用过的延时功能(定时器)实现方法。
接下来的几个例子,我们将在 ShowA 函数中延时 5 秒调用 ShowB 函数,通过代码来分析各个实现方法的异同。为了简洁,我仅截取部分关键代码,关于脚本是否继承 MonoBehaviour 等内容,请自行添加。
1. 使用 Update 函数实现定时器
float m_timer = 0;
void Update ()
{
// 这里应该使用 Time.deltaTime 来累加时间,而不是 Time.time
m_timer += Time.deltaTime;
if (m_timer >= 5)
{
ShowB();
m_timer = 0;
}
}
private void ShowB()
{
// 具体实现逻辑
}
使用 Update 函数实现定时器几乎是学习 Unity3D 的必修课。然而,在实际项目中,需要维护 m_timer 这个变量,并且从设计角度来看,代码的整洁度欠佳。
2. 使用 Invoke 函数实现定时器
GameController.Get().CancelInvoke();
GameController.Get().Invoke("ShowB", 5f);
private void ShowB()
{
game.ShowCardInTurn();
}
Invoke 是 MonoBehaviour 类提供的一个函数,它可以实现函数的延时调用,并且能够通过 CancelInvoke 方法控制调度器的停止。不过,Invoke 函数的调用是在运行时生效的。对于 ShowB 函数,在代码审查阶段很容易被误删,因为删除该函数后编译不会报错,可能会让人误以为这是一个废弃的函数。
3. 使用 Coroutine(协程)实现定时器
private IEnumerator ShowA()
{
yield return new WaitForSeconds(5);
ShowB();
}
private void ShowB()
{
// 具体实现逻辑
}
使用协程的 WaitForSeconds 方法可以轻松实现定时器功能,使用起来较为简单。
综上所述,这三种方法各有优劣。在实际开发中,需要根据具体的需求和场景来选择合适的延时功能实现方式。