計時器《一》:計時和倒計時,回調方法,計時類型

計時和倒計時,開始、進度及結束回調,計時類型,同時多個計時器計時...


using UnityEngine;
using System.Collections;
using System;
using WillData;

/// <summary>
/// 計時器工具類
/// </summary>
public class Timer : MonoBehaviour
{
    #region config

    /// <summary>
    /// 計時器開始計時
    /// </summary>
    public ClientData<float> TimerStartCallback;
    /// <summary>
    /// 計時器計時進度
    /// </summary>
    public ClientData<float> TimeProcessCallback;
    /// <summary>
    /// 計時器計時結束
    /// </summary>
    public ClientData<float> TimerCompletedCallback;

    /// <summary>
    /// 當前計時器時間
    /// </summary>
    public float _Now;

    public TimerType _timerType;
    bool _isLog = true;
    /// <summary>
    /// true:計時;false:倒計時
    /// </summary>
    bool _Dir; 

    float _Start; 
    float _Pause;
    /// <summary>
    /// 計時時間
    /// </summary>
    float _Target;
    /// <summary>
    /// 時間偏移量
    /// </summary>
    float _Offset = 0;
    float _NowTime; 
    /// <summary>
    /// 是否開始計時
    /// </summary>
    bool _isTimer;       
    /// <summary>
    /// 計時是否結束
    /// </summary>
    bool _isEnd;
    /// <summary>
    /// 忽略時間速率
    /// </summary>
    bool _isIgnoreTimeScale = true;  
    /// <summary>
    /// 是否重複計時
    /// </summary>
    bool _isRepeate;

    float _Time
    {
        get { return _isIgnoreTimeScale ? Time.realtimeSinceStartup : Time.time; }
    }

    #endregion

    void Update()
    {
        if (_isTimer)
        {
            TimeProcessCallback?.Invoke(_Now);

            if (_Dir)
            {
                _NowTime = _Time - _Offset;
                _Now = _NowTime - _Start;

                if (_Now > _Target)
                {
                    switch (_timerType)
                    {
                        case TimerType.TimeOut:
                            break;
                        case TimerType.CountDown:
                            if (GameData.ServerData.state == GameState.count)
                                TimerCompletedCallback?.Invoke(0);
                            break;
                        case TimerType.Waiting:
                            break;
                        case TimerType.Choice:
                            break;
                        case TimerType.Loading:
                            break;
                        case TimerType.Playing:
                            if (GameData.ServerData.state == GameState.play)
                                TimerCompletedCallback?.Invoke(0);
                            break;
                        case TimerType.Ending:
                            if (GameData.ServerData.state == GameState.end)
                                TimerCompletedCallback?.Invoke(0);
                            break;
                    }
                    if (!_isRepeate)
                    {
                        TimeOver();
                    }
                    else
                    {
                        ResetTimer();
                    }
                }
            }
            else
            {
                _NowTime = _Time - _Offset;
                _Now = _Target - (_NowTime - _Start);
                if (_Now <= 0)
                {
                    switch (_timerType)
                    {
                        case TimerType.TimeOut:
                            break;
                        case TimerType.CountDown:
                            if (GameData.ServerData.state == GameState.count)
                                TimerCompletedCallback?.Invoke(0);
                            break;
                        case TimerType.Waiting:
                            break;
                        case TimerType.Choice:
                            break;
                        case TimerType.Loading:
                            break;
                        case TimerType.Playing:
                            if (GameData.ServerData.state == GameState.play)
                                TimerCompletedCallback?.Invoke(0);
                            break;
                        case TimerType.Ending:
                            if (GameData.ServerData.state == GameState.end)
                                TimerCompletedCallback?.Invoke(0);
                            break;
                    }
                    if (!_isRepeate)
                    {
                        TimeOver();
                    }
                    else
                    {
                        ResetTimer();
                    }
                }
            }
        }
    }

    /// <summary>
    /// 創建計時器
    /// </summary>
    /// <param name="timerType">計時器類型</param>
    /// <returns></returns>
    public static Timer CreateTimer(TimerType timerType)
    {
        GameObject g = new GameObject(timerType.ToString());
        Timer timer = g.AddComponent<Timer>();
        timer._timerType = timerType;
        return timer;
    }

    public void EventHandler(ClientData<float> StartCallback = null, ClientData<float> ProcessCallback = null, ClientData<float> CompletedCallback = null)
    {
        TimerStartCallback += StartCallback;
        TimerCompletedCallback += CompletedCallback;
        TimeProcessCallback += ProcessCallback;
    }

    public void StartTimer(float time, bool dir = false, bool isIgnoreTimeScale = true, bool isRepeate = false)
    {
        Debug.Log(_timerType + " 開始計時。");
        TimerStartCallback?.Invoke(time);

        _Dir = dir;
        _Target = time;
        _Start = _Time;
        _Offset = 0;

        _isIgnoreTimeScale = isIgnoreTimeScale;
        _isRepeate = isRepeate;
        _isEnd = false;
        _isTimer = true;

    }

    void OnApplicationPause(bool state)
    {
        if (state)
        {
            Pause();
        }
        else
        {
            Timing();
        }
    }

    public void Pause()
    {
        if (_isEnd)
        {
            if (_isLog)
            {
                Debug.Log("Timer is over!");
            }
        }
        else
        {
            if (_isTimer)
            {
                _isTimer = false;
                _Pause = _Time;
            }
        }
    }

    public void Timing()
    {
        if (_isEnd)
        {
            if (_isLog)
            {
                Debug.Log("Timer is over!");
            }
        }
        else
        {
            if (!_isTimer)
            {
                _Offset += (_Time - _Pause);
                _isTimer = true;
            }
        }
    }

    public void ResetTimer()
    {
        _Start = _Time;
        _Offset = 0;
    }

    public void TimeOver()
    {
        _isTimer = false;
        _isEnd = true;
    }

}


 

namespace WillData
{
    public delegate void ClientData();
    public delegate void ClientData<T>(T data);

    /// <summary>
    /// 計時器類型
    /// </summary>
    public enum TimerType
    {
        TimeOut,
        CountDown,
        Waiting,
        Choice,
        Loading,
        Playing,
        Ending
    }

}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章