Unity计时器
游戏中有非常多的计时功能,比如:各种cd,以及需要延时调用的方法;
一般实现有一下几种方式:
1.手动计时
float persistTime = 10f float startTime = Time.time; if(Time.time - startTime > persistTime) {Debug.Log("计时结束"); }float curTime = 0; curTime += Time.deltaTime; if(curTime > persistTime) {Debug.Log("计时结束"); }
2:协程
private float persistTime = 10f; IEnumerator DelayFunc() {yield return persistTime;Debug.Log("计时结束"); }private void Start() {StartCoroutine(DelayFunc()); }
3.Invoke回调
private void Start() {Invoke("DelayFunc", persistTime); }
计时器功能
计时是为了到特定的时间,执行某个功能或方法;
计时器(Timer):设计了计时暂停,计时重置,计时开始方法,计时中方法,计时结束方法,固定间隔调用方法,计时器可设置复用或单次;
计时管理器(TimerMa):负责倒计时,以及执行计时器方法;
代码:
using System; using System.Collections.Generic; using UnityEngine; using Object = System.Object;public class Timer {public delegate void IntervalAct(Object args);//总时间和当前持续时间private float curtime = 0;private float totalTime = 0;//激活public bool isActive;//计时结束是否销毁public bool isDestroy;//是否暂停public bool isPause;//间隔事件和间隔事件——Dotprivate float intervalTime = 0;private float curInterval = 0;private IntervalAct onInterval;private Object args;//进入事件public Action onEnter;private bool isOnEnter = false;//持续事件public Action onStay;//退出事件public Action onEnd;public Timer(float totalTime, bool isDestroy = true, bool isPause = false){curtime = 0;this.totalTime = totalTime;isActive = true;this.isDestroy = isDestroy;this.isPause = isPause;TimerMa.I.AddTimer(this);}public void Run(){//暂停计时if (isPause || !isActive)return;if (onEnter != null){if (!isOnEnter){isOnEnter = true;onEnter();}}//持续事件if (onStay != null)onStay();curtime += Time.deltaTime;//间隔事件if (onInterval != null){curInterval += Time.deltaTime;if (curInterval > intervalTime){onInterval(args);curInterval = 0;}}//计时结束if (curtime > totalTime){curtime = 0;isActive = false;if (onEnd != null){onEnd();}} }//设置间隔事件public void SetInterval(float interval, IntervalAct intervalFunc, Object args = null){this.intervalTime = interval;onInterval = intervalFunc;curInterval = 0;this.args = args;}//重置计时器public void Reset(){curtime = 0;isActive = true;isPause = false;curInterval = 0;isOnEnter = false;}//获取剩余时间public float GetRemainTime(){return totalTime - curtime;} }
using System; using System.Collections; using System.Collections.Generic; using UnityEngine;public class TimerMa : MonoBehaviour {#region 单例private static TimerMa instance;TimerMa() {}public static TimerMa I{get{if (instance == null)instance = new TimerMa();return instance;}}#endregionprivate List<Timer> timerList;private void Awake(){instance = this;timerList = new List<Timer>();}public void AddTimer(Timer t){timerList.Add(t);}void Update(){for (int i = 0; i < timerList.Count;){timerList[i].Run();//计时结束,且需要销毁if(!timerList[i].isActive && timerList[i].isDestroy)timerList.RemoveAt(i);else++i;}} }
测试计时器
using System.Collections; using System.Collections.Generic; using UnityEngine; using UnityEngine.UI; using Object = System.Object;public class Test : MonoBehaviour {public Text mText1;public Text mText2;private Timer timer;private int count = 0;void Start(){timer = new Timer(5f,false);timer.SetInterval(1f, OnInterval);timer.onEnter = OnStart;timer.onEnd = OnExit;}void Update(){Debug.Log(count);mText1.text = timer.GetRemainTime().ToString("f2");if (Input.GetKeyDown(KeyCode.A)){if (!timer.isPause){timer.isPause = true;mText2.text = "暂停计时";}}if (Input.GetKeyDown(KeyCode.S)){if (timer.isPause){timer.isPause = false;mText2.text = "取消暂停计时";}}if (Input.GetKeyDown(KeyCode.D)){timer.Reset();mText2.text = "重置计时";}}private void OnStart(){mText2.text = "开始计时";}private void OnExit(){mText2.text = "结束计时";}private void OnInterval(Object value){count++;mText2.text = $"间隔事件调用{count}";} }