在Unity中很多时候,需要让某一事件在指定的时间间隔执行一次。这个时间间隔可能是固定的,也可能是不固定的。
一、在 Update 函数中,利用 Time.time 来制作计时器
1、时间间隔固定多久执行一次。interval 为计时器的间隔,为固定不变。
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Timer : MonoBehaviour
{
public float startTime;
public float curTime;
public float interval = 2.0f; // 计时器的时间间隔
void Start () {
// Time.time 从游戏开始到此刻所经历的时间,以秒为单位
startTime = Time.time;
}
void Update () {
curTime = Time.time;
if (curTime - startTime > interval)
{
Debug.Log("A cycle about 2.0 s");
startTime = curTime;
}
}
}
2、时间间隔不固定,将每次执行所需要的时间间隔放在一个数组中,每次分别和其进行比较。
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Timer : MonoBehaviour
{
public float startTime;
public float curTime;
public float[] interval = { 0.8f, 1.2f, 1.5f, 1.1f, 0.9f, 1.8f, 2.0f, 2.2f };
int num = 0;
public bool flag = true;
void Start () {
// Time.time 从游戏开始到此刻所经历的时间,以秒为单位
startTime = Time.time;
}
void Update () {
if (flag)
{
curTime = Time.time;
if (curTime - startTime > interval[num])
{
Debug.Log("A cycle time");
startTime = curTime;
if (num < interval.Length-1)
{
num++;
}
else
{
flag = false;
}
}
}
}
}
二、在 Start () 函数中使用 InvokeRepeating () 函数
1、时间间隔固定多久执行一次。interval 为计时器的间隔,为固定不变。
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Timer : MonoBehaviour
{
public float startTime = 1.6f; // 开始执行的时间
public float interval = 2.0f; // 开始执行之后,每次执行的时间间隔
private void Start()
{
InvokeRepeating("DoCycle", startTime, interval);
}
void DoCycle()
{
Debug.Log("A cycle time");
}
}
2、时间间隔不固定,将每次执行所需要的时间间隔放在一个数组中,每次分别和其进行比较。
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Timer : MonoBehaviour
{
public float startTime = 0.5f;
public float[] interval = { 0.8f, 1.2f, 1.5f, 1.1f, 0.9f, 1.8f, 2.0f, 2.2f };
public int num = 0;
private void Start()
{
InvokeRepeating("DoCycle", startTime, interval[num]);
}
void DoCycle()
{
Debug.Log("A cycle time");
if (num < interval.Length - 1)
{
num++;
}
else
{
CancelInvoke();
}
}
}
三、使用协程 StartCoroutine
1、时间间隔固定多久执行一次。interval 为计时器的间隔,为固定不变。
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System;
public class Timer : MonoBehaviour
{
public float interval = 0.8f;
public int num = 0;
private void Start()
{
// 启动协程
StartCoroutine(ATimer());
}
void DoCycle(int k)
{
Debug.Log("A cycle time "+k);
}
IEnumerator ATimer()
{
while (true)
{
DoCycle(num);
num++;
yield return new WaitForSeconds(interval);
}
}
}
2、时间间隔不固定,将每次执行所需要的时间间隔放在一个数组中,每次分别和其进行比较。
(1)、针对时间间隔不固定的情况下,常用的方案。
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Timer : MonoBehaviour
{
public float[] interval = { 0.8f, 1.2f, 1.5f, 1.1f, 0.9f, 1.8f, 2.0f, 2.2f };
public int num = 0;
private void Start()
{
StartCoroutine(ATimer());
}
void DoCycle(int k)
{
Debug.Log("A cycle time " + k);
}
IEnumerator ATimer()
{
while (true)
{
DoCycle(num);
if (num < interval.Length - 1)
{
num++;
yield return new WaitForSeconds(interval[num]);
}
else
{
break;
}
}
}
}
(2)、在另一种情况下,需要判断某个条件是否满足,只有在该条件满足的情况下,才去执行这个计时器内的内容。设该条件为 flag ,
在游戏运行到某一个种情况下,flag 的值变为 true ,此时才开始执行计时器中的内容。在这种情况下,对应的代码如下:
【注】:如下的代码需要两个 break 来跳出该循环
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Timer : MonoBehaviour
{
public float[] TimeInterval = { 0.8f, 1.2f, 1.5f, 1.1f, 0.9f, 1.8f, 2.0f, 2.2f };
public int num = 0;
bool flag = false;
private void Start()
{
StartCoroutine(ATimer());
}
void DoCycle(int k)
{
Debug.Log("A cycle time " + k);
}
IEnumerator ATimer()
{
while (true)
{
yield return new WaitForEndOfFrame();
if (flag)
{
for (int k = 0; k < TimeInterval.Length; k++)
{
DoCycle(k);
if (k < TimeInterval.Length - 1)
{
yield return new WaitForSeconds(TimeInterval[k]);
}
else
{
break;
}
}
break;
}
}
}
}
参考资料:
[1] 关于Unity中的简易定时器
[2] Unity3D 计时器的三种写法