Unity 模拟协程实现计时器功能

众所周知,在Unity里面开启协程会有消耗,有时候就算我们只需要用到一个简单的计时器,必须开一个协程或者自己写一个计时器。这里提供了一个通用的计时器类,里面还实现了内存池管理,使用完的计时器回收备用。

使用方法:只需负责调用即可,内部会自动回收。


using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System;

public class GlobalTimer : MonoBehaviour
{
    private static GlobalTimer instance;
    public static GlobalTimer Instance
    {
        get
        {
            if (!instance)
            {
                instance = GameObject.FindObjectOfType
   
   
    
    ();
            }
            if (!instance)
            {
                GameObject obj = new GameObject(typeof(GlobalTimer).ToString());
                instance = obj.AddComponent
    
    
     
     ();
            }
            return instance;
        }
    }

    //正在使用的TimerData
    private List
     
     
      
       mUseTimerDatas = new List
      
      
       
       ();
    //空闲的TimerData
    private List
       
       
         mNotUseTimerDatas = new List 
        
          (); //尝试从空闲池中取一个TimerData private TimerData GetTimerData(bool isAdd = true) { TimerData data = null; if (mNotUseTimerDatas.Count <= 0) { data = new TimerData(); } else { data = mNotUseTimerDatas[0]; mNotUseTimerDatas.RemoveAt(0); } mUseTimerDatas.Add(data); return data; } //创建一个计时器 public TimerData AddTimer(float _duration, Action endCallBack, bool _isIgnoreTime = false) { TimerData data = GetTimerData(); data.Init(_duration, endCallBack, _isIgnoreTime); return data; } //创建一个重复型计时器 public TimerData AddIntervalTimer(float _duration, float _interval, Action _endCallBack, Action 
         
           _intervalCallBack, bool _isIgnoreTime = false) { TimerData data = GetTimerData(); data.Init(_duration, _endCallBack, _isIgnoreTime, _interval, _intervalCallBack); return data; } protected void Clear(TimerData data) { if (mUseTimerDatas.Remove(data)) { mNotUseTimerDatas.Add(data); } else { Debug.LogWarning("GlobalTimer not find TimerData"); } } #region 测试代码 void Start() { TimerData td1 = GlobalTimer.Instance.AddTimer(5, () => { Debug.Log("5秒后调用该方法1"); }); TimerData td2 = GlobalTimer.Instance.AddIntervalTimer(5, 1, () => { Debug.Log("5秒后调用该方法2"); }, (float remainTime) => { Debug.Log("每一秒调用执行此处:剩余时间" + remainTime); } ); } #endregion void Update() { for (int i = 0; i < mUseTimerDatas.Count; ++i) { if (!mUseTimerDatas[i].Update()) { //没更新成功,mUseTimerDatas长度减1,所以需要--i --i; } } } public class TimerData { //持续时间 private float mDuration; //重复间隔 private float mInterval; //结束回调 private Action mEndCallBack; //每次重复回调 private Action 
          
            mIntervalCallBack; //是否忽略时间 private bool isIgnoreTime; //计时器 private float mRunTime; //间隔计时器 private float mRunIntervalTime; //初始化 public void Init(float _duration, Action _endCallBack, bool _isIgnoreTime = false, float _interval = -1f, Action 
           
             _intervalCallBack = null) { mDuration = _duration; mInterval = _interval; mEndCallBack = _endCallBack; mIntervalCallBack = _intervalCallBack; isIgnoreTime = _isIgnoreTime; mRunTime = 0; mRunIntervalTime = 0; } //更新 public bool Update() { float deltaTime = isIgnoreTime ? Time.unscaledDeltaTime : Time.deltaTime; mRunTime += deltaTime; mRunIntervalTime += deltaTime; if (mIntervalCallBack != null) { if (mRunIntervalTime >= mInterval) { mRunIntervalTime -= mInterval; mIntervalCallBack(mDuration - mRunTime); } } if (mRunTime >= mDuration) { if (mEndCallBack != null) { mEndCallBack(); } Clear(); return false; } return true; } public void Clear() { instance.Clear(this); } public void AddEndCallBack(Action _endCallBack) { mEndCallBack += _endCallBack; } } } 
            
           
          
         
       
      
      
     
     
    
    
   
   



  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值