Calmer的文章

  • 首页
  • 文章归档
  • 关于页面

  • 搜索
体验游戏 笔记 推荐 工具链 工具使用 小游戏 插件 UI 软件 教程

TimerUtils工具(时间、定时器、间隔执行)

发表于 2020-04-02 | 分类于 游戏开发 | 0 | 阅读次数 883

前言

用于时间管理、定时执行函数、间隔执行函数

核心代码

  • TimeTween.cs
using System;
public enum TweenType
{
    ToDelay,
    IntervalCall,
}

public class TimeTween
{
    public int tweenId
    {
        get
        {
            return id;
        }
        set
        {
            id=value;
        }
    }

    private int id;
    private float duringTime;
    private Action callback;
    private float runTime;
    private float spanTime;
    private float spanTimer;
    private TweenType? tweenType;

    public TimeTween()
    {
        Init();
    }

    public void Init()
    {
        id=-1;
        duringTime=0.0f;
        runTime=0.0f;
        spanTimer=0.0f;
        spanTime=0.0f;
        callback=null;
        tweenType=null;
    }

    public void ToDelay(int id,float time,Action callback)
    {
        this.id=id;
        tweenType=TweenType.ToDelay;
        duringTime=time;
        this.callback=callback;
        runTime=0.0f;
    }

    public void IntervalCall(int id,float spanTime,Action callback,float duringTime)
    {
        this.id=id;
        tweenType=TweenType.IntervalCall;
        this.duringTime=duringTime;
        this.callback=callback;
        runTime=0;
        spanTimer=spanTime;
        this.spanTime=spanTime;
    }

    public bool CheckEnd()
    {
        return runTime>=duringTime;
    }

    public void SetCallback(Action action)
    {
        callback=action;
    }

    public void Finish(bool isFinish=false,int needCallback=0)
    {
        if(needCallback==0)
        {
            if(tweenType.Value==TweenType.ToDelay && callback!=null)
            {
                callback();
            }
        }
        else if(needCallback==1)
        {
            callback?.Invoke();
        }
    }

    public bool TweenTo(float deltaTime)
    {
        bool needKill=false;
        runTime+=deltaTime;
        switch(tweenType.Value)
        {
            case TweenType.ToDelay:
                break;
            case TweenType.IntervalCall:
                spanTimer+=deltaTime;
                if(spanTimer>=spanTime)
                {
                    spanTimer-=spanTime;
                    try
                    {
                        callback?.Invoke();
                    }
                    catch(Exception e)
                    {
                        needKill=true;
                    }
                }
                break;
        }
        if(CheckEnd())
        {
            needKill=true;
            if(callback!=null &&tweenType.Value!=TweenType.IntervalCall)
            {
                callback();
            }
        }
        return needKill;
    }
}
  • TimerUtils.cs
using System.Collections.Generic;
using System;

public static class TimerUtils
{
    private static Dictionary<int,TimeTween> tweenList=new Dictionary<int,TimeTween>();
    private static List<TimeTween> cacheList=new List<TimeTween>();

    private const int maxNum=1024;

    private static int count=0;
    private const int cacheMaxNum=32;
    private static int idCounter=0;

    private static void Add(TimeTween tween)
    {
        if(!tweenList.ContainsKey(tween.tweenId))
        {
            tweenList.Add(tween.tweenId,tween);
            count++;
        }
    }

    private static void Remove(TimeTween tween)
    {
        if(tweenList.ContainsKey(tween.tweenId))
        {
            AddToCache(tween);
            tweenList.Remove(tween.tweenId);
            count--;
        }
    }

    private static bool IsPlaying(TimeTween tween)
    {
        if(tweenList.ContainsKey(tween.tweenId))
            return true;
        else
            return false;
    }

    private static void AddToCache(TimeTween tween)
    {
        if(cacheList.Count<cacheMaxNum)
        {
            cacheList.Add(tween);
        }
    }

    private static TimeTween GetFromCache()
    {
        TimeTween tween=null;
        if(cacheList.Count>0)
        {
            tween=cacheList[0];
            cacheList.Remove(tween);
        }
        return tween;
    }

    private static TimeTween GetNewTween()
    {
        TimeTween curTween=null;
        curTween=GetFromCache();
        if(curTween!=null)
        {
            int tweenId=curTween.tweenId;
            curTween.Init();
            curTween.tweenId=tweenId;
        }
        else
        {
            curTween=new TimeTween();
            idCounter++;
            curTween.tweenId=idCounter;
        }
        return curTween;
    }

    public static TimeTween ToDelay(float duringTime,Action callback)
    {
        TimeTween curTween=null;
        if(duringTime>0)
        {
            if(count<maxNum)
            {
                curTween=GetNewTween();
                curTween.ToDelay(curTween.tweenId,duringTime,callback);
                Add(curTween);
            }
        }
        return curTween;
    }

    public static TimeTween IntervalCall(float spanTime,Action callback,float duringTime)
    {
        TimeTween curTween=null;
        if(duringTime>0&&spanTime>0)
        {
            if(count<maxNum)
            {
                curTween=GetNewTween();
                curTween.IntervalCall(curTween.tweenId,duringTime,callback);
                Add(curTween);
            }
        }
        return curTween;
    }

    public static void Kill(TimeTween tween,bool isFinish=false)
    {
        if(tween!=null)
        {
            if(IsPlaying(tween))
            {
                Remove(tween);
                if(isFinish)
                {
                    tween.Finish(true,0);
                }
            }
        }
    }

    public static void KillWithCallback(TimeTween tween,bool isFinish=false,bool needCallback=false)
    {
        if(tween!=null)
        {
            if(IsPlaying(tween))
            {
                Remove(tween);
                if(isFinish)
                {
                    if(needCallback)
                    {
                        tween.Finish(true,1);
                    }
                    else
                    {
                        tween.Finish(true,-1);
                    }
                }
                else
                {
                    if(needCallback)
                    {
                        tween.Finish(false,1);
                    }
                }
            }
        }
    }

    public static bool CheckEnd(TimeTween tween)
    {
        return tween!=null && tween.CheckEnd();
    }

    public static void ChanageCallback(TimeTween tween,Action action)
    {
        tween?.SetCallback(action);
    }

    public static void Update(float deltaTime)
    {
        if(count>0)
        {
            int[] keyArr=new int[tweenList.Count];
            tweenList.Keys.CopyTo(keyArr,0);
            for(int i=0;i<keyArr.Length;i++)
            {
                bool needKill=tweenList[keyArr[i]].TweenTo(deltaTime);
                if(needKill)
                {
                    Remove(tweenList[keyArr[i]]);
                }
            }
        }
    }
}

说明:只需要将TimerUtils 中的Update放入Unity主Update进行驱动,
然后调用相应的ToDelay和IntervalCall函数即可。

  • ToDelay:延迟duringTime秒执行callback
  • IntervalCall:间隔spanTime秒执行一次callback,总共持续多久duringTime秒
  • InTimeCall:具体时间进行执行

扩展:以上工具方法还能扩展到对值的缓动进行补间运算。实现类似于DOTween的之变换效果。

  • 本文作者: Calmer
  • 本文链接: https://mytechplayer.com/archives/tweenutils工具
  • 版权声明: 本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明出处!
# 工具使用
DoTween的使用
游戏开发_小游戏开发(2048)(上)
  • 文章目录
  • 站点概览
Calmer

Calmer

88 日志
7 分类
10 标签
RSS
Creative Commons
0%
© 2020 — 2025 Calmer
由 Halo 强力驱动
蜀ICP备20010026号-1川公网安备51019002006543
Copyright © 2020-2025 Calmer的文章