Unity Timer两种计时器

2023-12-28 15:00:03

Timer两种计时器

一、倒计时计时器(常用语UI倒计时显示)

这个计时器是一个继承自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();
        }
    }
}

二、技能CD计时器

代码如下:

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();
        }
    }
}

文章来源:https://blog.csdn.net/qq_42194657/article/details/135192504
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。