程序和游戏中往往有很多需要计时的地方,比如很多日常任务是领取后倒计时到了就可以完成的。于是之前做游戏的时候设计了一个计时类Timer,需要使用的时候实例化一个Timer,并且在Update中进行计时即可。
首先确定实现计时器需要哪些变量和功能。我们需要判断计时器是否在工作,总的计时时长,当前的计时时长和计时的进程。我们还需要一些简单的方法,如开始,暂停,恢复,停止等,当然在各个方法执行的时候能够针对不同的情况相应一些事件也是必须的,不然这个计时器就不具备了通用性。知道了这些我们就可以开始设计我们的计时器了,其中计时器已秒为单位,我们可以进行更改定义自己需要的单位。
首先定义一些变量,这里使用了Get和Set来设置属性。
private bool _running;
private float _curTime;
private float _targetTime;
private float _process;
public float tartetTime
{
get { return _targetTime; }
}
public float process
{
get
{
return _process;
}
set
{
_process = Mathf.Clamp01(value);
_curTime = _targetTime * _process;
}
}
public bool IsRunning()
{
return _running;
}
然后我们用委托机制来实现我们需要自定义的事件。
public delegate void EventHandler();
// 计时器开始事件
public event EventHandler startEvent;
// 计时器计时事件
public event EventHandler tickEvent;
// 计时器结束事件
public event EventHandler endEvnet;
// 计时器暂停事件
public event EventHandler pauseEvent;
// 计时器停止事件
public event EventHandler stopEvent;
// 计时器重置事件
public event EventHandler resetEvent;
当我们实例化一个Timer对象之后,只需添加对应的事件即可,当然是用+=时不要忘记在合适的事件对应地-=。
Timer timer = new Timer();
void OnEnable()
{
timer.endEvent += OnTimerEnd;
}
void OnDisable()
{
timer.endEvent -= OnTimerEnd;
}
void OnTimerEnd()
{
Debug.Log("Timer End");
}
当然我们实例化计时类的时候需要一个目标值,并且设置是否自动启动计时器。当然我们也可以定义一些自己需要的内容,比如在特定的时间点处启动等。代码如下:
public Timer(float target, bool autoStart)
{
if (target < 0)
{
#if UNITY_EDITOR
Debug.Log("Target time must larger than 0");
#endif
target = 0;
}
_targetTime = target;
_curTime = 0;
_process = 0;
_running = autoStart;
}
最后就是控制计时器的一个方法,比如开始,暂停之类的,在每个方法中调用定义的委托事件。在调用之前需要先判断一下是否有委托,不然会报错。
public void TimerStart()
{
_running = true;
if (startEvent != null)
startEvent();
}
public void TimerPause()
{
_running = false;
if (pauseEvent != null)
pauseEvent();
}
public void TimerStop()
{
_process = 0;
_curTime = 0;
_running = false;
if (stopEvent != null)
stopEvent();
}
public void TimerReset()
{
_process = 0;
_curTime = 0;
_running = false;
if (resetEvent != null)
resetEvent();
}
public void ReStartTimer()
{
_process = 0;
_curTime = 0;
_running = true;
if (startEvent != null)
startEvent();
}
最后也是最重要的一个函数,就是实现计时器计时功能的方法,这个方法需要在脚本的Update中进行调用,或者在协程等一些可以计时的地方进行调用。我们给这个函数传入一个float类型的时间间隔,让计时器不断更新当前时间,当进行到达1的时候计时就结束了。
public void TimerTick(float deltaTime)
{
if (_running)
{
_curTime += deltaTime;
_process = _curTime / _targetTime;
if (tickEvent != null)
tickEvent();
if (_process >= 1)
{
_process = 1;
_curTime = _targetTime;
_running = false;
if (endEvnet != null)
endEvnet();
}
}
}
在我们需要使用计时器的脚本中,建议先判断计时器是否为null来避免我们删除计时器后的报错情况:
Timer timer = new Timer(60, true);
void Update()
{
if(timer != null)
}
源码:
百度网盘
密码:nvfg
by:蒋志杰