计时器实现方法:
- 使用Time.deltaTime累加方式
在Update里面,使用Time.deltaTime实现:
using UnityEngine;
public class Test : MonoBehaviour
{
//使用Time.deltaTime实现
public float timer = 2f;
//或者通过Time.time来实现:
public float timer1 = 0f;
void Start()
{
timer1 = Time.time;
timer = 2f;
}
void Update()
{
//使用Time.deltaTime实现
timer -= Time.deltaTime;
if (timer <= 0)
{
do();
timer = 2f; // 定时2秒
}
//或者通过Time.time来实现:
timer1 += Time.deltaTime;
if (Time.time - timer1 >= 2)// 定时2秒
{
do();
timer1 = Time.time;
}
}
void do()
{
Debug.Log("每2秒执行一次");
}
}
- 使用延迟调用函数
using UnityEngine;
public class Test : MonoBehaviour
{
void Start()
{
//0秒后,每1秒执行一次do
InvokeRepeating("do", 0, 1);
}
void do()
{
Debug.Log("每1秒执行一次");
}
}
- 使用协程
using System;
using System.Collections;
using UnityEngine;
public class Test : MonoBehaviour
{
void Start()
{
//每1秒执行一次do
StartCoroutine(do());
//如果写入参数do()报红,可以写成以下调用形式
//StartCoroutine("do");
}
IEnumerator do()
{
while (true)
{
yield return new WaitForSeconds(1f);
Debug.Log("每1秒执行一次");
}
}
}
协程与InvokeRepeating相较值得注意的是:
- 与标准函数调用相比,启动协程会带来额外的开销成本(大约是标准函数调用的3倍),还会分配一些存储当前状态在内存中,直到下一次调用它。
- 一旦初始化,它的执行独立于Monobehaviour组件中的Update回调的触发,不管Monobehaviour组件是否禁用,都将继续调用协程。
- 协程会在包含它的GameObject变成不活动的那一刻自动停止,尽管再次设置该GameObject为活动的,协程是不会重新启动的。
- 协程不遵循正常的执行流程,它们可能在其他代码系统不希望的时刻触发,因此,最好让其独立于其他复杂的子系统。
InvokeRepeating与协程的重要区别是,完全独立于MonoBehaviour和Gameobject的状态,因此停止它的方式有2种:
- 调用CancelInvoke()
- 销毁关联的MonoBehaviour或GameObject。禁用MonoBehaviour或GameObject都不会停止InvokeRepeating。