定时若干秒回调
协程任务可以做定时器,但是有个最大的问题,那就是必须要在脚本中使用,为了方便使用,所以封装一个不依赖脚本实现的定时器。
using System.Collections;
using UnityEngine;
using UnityEngine.Events;
public class WaitTimeManager
{
private static TaskBehaviour m_Task;
static WaitTimeManager()
{
GameObject go = new GameObject("WaitTimeManager");
GameObject.DontDestroyOnLoad(go);
m_Task = go.AddComponent<TaskBehaviour>();
}
public static void CancelWait(ref Coroutine coroutine)
{
if (coroutine!=null)
{
m_Task.StopCoroutine(coroutine);
}
}
public static Coroutine WaitTime(float time, UnityAction callback)
{
return m_Task.StartCoroutine(Coroutine(time, callback));
}
private static IEnumerator Coroutine(float time, UnityAction callback)
{
yield return new WaitForSeconds(time);
if (callback!=null)
{
callback();
}
}
//内部类
class TaskBehaviour : MonoBehaviour
{
}
}
无论是脚本还是类,在需要的时候调用它即可,相关代码如下:
//开启定时器
Coroutine coroutine = WaitTimeManager.WaitTime(5, () =>
{
print("5秒钟过去啦");
});
//等待过程中取消它
WaitTimeManager.CancelWait(ref coroutine);
每秒回调
上个定时器满足了经过多少秒回调的需求,但是游戏可能还需要每秒钟都回调一次,例如显示时间。如代码所示,继承CustomYieldInstrunction后,就可以处理自定义协程程序了。其中KeepWaiting表示是否继续让协程等待,通过时间判断,即可算出是否抛出间隔事件。
using UnityEngine;
using UnityEngine.Events;
public class CustomWait:CustomYieldInstruction
{
public override bool keepWaiting
{
get
{
//此方法通过返回false表示协程结束
if (Time.time-m_StatTime>=m_Time)
{
return false;
}else if (Time.time - m_LastTime >= m_Interval)
{
m_LastTime = Time.time;
m_IntervalCallback();
}
return true;
}
}
private UnityAction m_IntervalCallback;
private float m_StatTime;
private float m_LastTime;
private float m_Interval;
private float m_Time;
/// <param name="time">执行的总共时间</param>
/// <param name="interval">每隔几秒调用一次</param>
/// <param name="callback"></param>
public CustomWait(float time, float interval, UnityAction callback)
{
m_StatTime = Time.time;
m_LastTime = Time.time;
m_Time = time;
m_Interval = interval;
m_IntervalCallback = callback;
}
}
最后,还有其他方法也能实现定时器,可以参考Unity延时功能的几种实现。