这个计时器是一个继承自MonoBehavior的脚本,使用的时候直接使用静态方法创建即可
可以同时控制多个物体互相不影响
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public delegate void TimerCompleteEvent();
public delegate void UpdateEvent(int t);
public class Timer : MonoBehaviour {
/// <summary>
/// 完成委托
/// </summary>
TimerCompleteEvent del;
/// <summary>
/// 实时委托
/// </summary>
UpdateEvent updatedel;
/// <summary>
/// 总秒数
/// </summary>
private int second = 10;
/// <summary>
/// 上前的时间
/// </summary>
private int previous = 10;
/// <summary>
/// 开关
/// </summary>
public bool isopen = false;
/// <summary>
/// 计时使用
/// </summary>
private float totalTime = 0;
/// <summary>
/// 计时器
/// </summary>
private void Timers()
{
//累加每帧消耗时间
totalTime += Time.deltaTime;
if (second == 0)
{
if (del != null)
{
del();
}
StopTimer();
}
if (totalTime >= 1)//每过1秒执行一次
{
second--;
totalTime = 0;
if (updatedel != null) updatedel(second);
}
}
/// <summary>
/// 开启计时器
/// </summary>
public void StartTimer(int total, TimerCompleteEvent timedel,UpdateEvent update)
{
totalTime = 0;
second = total;
previous = total;
isopen = true;
del = timedel;
updatedel = update;
}
/// <summary>
/// 创建计时器
/// </summary>
/// <param name="name"></param>
/// <returns></returns>
public static Timer CreateTimer(string name)
{
GameObject m_currTimer = new GameObject(name);
Timer time = m_currTimer.AddComponent<Timer>();
return time;
}
/// <summary>
/// 暂停计时器
/// </summary>
public void PauseTimer()
{
isopen = false;
}
/// <summary>
/// 继续计时器
/// </summary>
public void Continue()
{
isopen = true;
}
/// <summary>
/// 重新计时
/// </summary>
public void ReStartTimer()
{
second = previous;
totalTime = 0;
}
/// <summary>
/// 停止计时
/// </summary>
public void StopTimer()
{
if (this == null) return;
isopen = false;
totalTime = 0;
del = null;
updatedel = null;
Destroy(gameObject);
}
private void Update()
{
if (isopen)
{
Timers();
}
}
}
using UnityEngine;
public class TimerCtrl : MonoBehaviour {
Timer tim;
// Use this for initialization
void Start () {
tim = Timer.CreateTimer("TimerCtrl1");
tim.StartTimer(10,()=>
{
Debug.LogError("TimerCtrl1完成");
},(time)=> {
Debug.LogError("TimerCtrl1:"+time);
});
}
// Update is called once per frame
void Update () {
if (Input.GetKeyDown(KeyCode.Q))
{
tim.PauseTimer();
}
if (Input.GetKeyDown(KeyCode.W))
{
tim.ReStartTimer();
}
if (Input.GetKeyDown(KeyCode.E))
{
tim.StopTimer();
}
}
}
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public delegate void FinishEventHandler();
public delegate void UpdateEventHandler(float time);
public class MyTimer : MonoBehaviour {
/// <summary>
/// 打印开关
/// </summary>
public bool isLog = true;
/// <summary>
/// 实时调用委托
/// </summary>
UpdateEventHandler updateEvent;
/// <summary>
/// 实时调用委托
/// </summary>
FinishEventHandler finishEvent;
/// <summary>
/// 计时时间
/// </summary>
float timeTarget;
/// <summary>
/// 开始计时时间
/// </summary>
float timeStart;
/// <summary>
/// 现在时间
/// </summary>
float timeNow;
/// <summary>
/// 计时偏差
/// </summary>
float offsetTime;
/// <summary>
/// 是否开始计时
/// </summary>
bool isTimer;
/// <summary>
/// 计时结束后是否销毁
/// </summary>
bool isDestory = true;
/// <summary>
/// 计时是否结束
/// </summary>
bool isEnd;
/// <summary>
/// 是否忽略时间速率
/// </summary>
bool isIgnoreTimeScale = true;
/// <summary>
/// 是否重复
/// </summary>
bool isRepeate;
/// <summary>
/// 真实时间
/// </summary>
float _Time
{
get
{
/// realtimeSinceStartup 是开始运行的时间切换应用不对其影响(真是时间)
/// time 是开始运行的时间切换应用不对其影响(实际时间)
return isIgnoreTimeScale ? Time.realtimeSinceStartup : Time.time;
}
}
/// <summary>
/// 当前所用时间
/// </summary>
float now;
private void Update()
{
if (!isTimer) return;
timeNow = _Time - offsetTime;
now = timeNow - timeStart;
if (updateEvent != null) updateEvent(Mathf.Clamp01(now/timeTarget));//与目标值的比例当为1的时候完成
if (now > timeTarget) //超过目标值
{
if (finishEvent != null) finishEvent();
if (!isRepeate) Destory();
else ReStartTimer();
}
}
/// <summary>
/// 经过的时间
/// </summary>
/// <returns></returns>
public float GetLeftTime()
{
return Mathf.Clamp(timeTarget - now,0,timeTarget);
}
private void OnApplicationPause(bool pause)
{
if (pause)
{
PauseTimer();
}
else
{
ConnitueTimer();
}
}
/// <summary>
/// 计时结束
/// </summary>
private void Destory()
{
isTimer = false;
isEnd = true;
if (isDestory) Destroy(gameObject);
}
/// <summary>
/// 暂停时间
/// </summary>
float _pauseTime;
/// <summary>
/// 暂停计时器
/// </summary>
public void PauseTimer()
{
if (isEnd)
{
if (isLog) Debug.LogError("计时已经结束");
}
else
{
if (isTimer)
{
isTimer = false;
_pauseTime = _Time;
}
}
}
/// <summary>
/// 重新计时
/// </summary>
public void ConnitueTimer()
{
if (isEnd)
{
if (isLog) Debug.LogError("计时已经结束!请重新开始!");
}
else
{
if (!isTimer)
{
offsetTime += (_Time - _pauseTime);
isTimer = true;
}
}
}
/// <summary>
/// 重新计时
/// </summary>
public void ReStartTimer()
{
if (!isTimer) isTimer = true;
if (isEnd) isEnd = false;
timeStart = _Time;
offsetTime = 0;
_pauseTime = 0;
}
/// <summary>
/// 停止计时器
/// </summary>
public void StopTimer()
{
Destory();
}
/// <summary>
/// 开始计时
/// </summary>
public void StartTiming(float _time,FinishEventHandler finishdel,UpdateEventHandler updatedel = null, bool _isIgnoreTimeScale = true, bool _isRepeate = false,bool _isDestory = true)
{
//设置目标时长
timeTarget = _time;
//设置委托
if (finishdel != null) finishEvent = finishdel;
if (updatedel != null) updateEvent = updatedel;
isDestory = _isDestory;
isIgnoreTimeScale = _isIgnoreTimeScale;
isRepeate = _isRepeate;
timeStart = _Time;
offsetTime = 0;
isEnd = false;
isTimer = true;
}
/// <summary>
/// 创建计时器:名字
/// </summary>
/// <returns></returns>
public static MyTimer CreateTimer(string objName = "Timer")
{
GameObject go = new GameObject(objName);
MyTimer timer = go.AddComponent<MyTimer>();
return timer;
}
}
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class MyTimer1 : MonoBehaviour {
MyTimer myTimer;
// Use this for initialization
void Start () {
myTimer = MyTimer.CreateTimer();
myTimer.StartTiming(5,()=>{
Debug.LogError("完成回调=====>");
},(t)=> {
Debug.LogError("实时刷新Timer1=="+t);
});
}
// Update is called once per frame
void Update () {
if (Input.GetKeyDown(KeyCode.Q))
{
myTimer.PauseTimer();
}
if (Input.GetKeyDown(KeyCode.W))
{
myTimer.ConnitueTimer();
}
if (Input.GetKeyDown(KeyCode.E))
{
myTimer.ReStartTimer();
}
if (Input.GetKeyDown(KeyCode.R))
{
myTimer.StopTimer();
}
}
}