代码拉取完成,页面将自动刷新
using System;
using System.Collections.Generic;
using UnityEngine;
/// <summary>
/// 基于运行系统时间的时钟,可获得对应的时间,或者设置Timer
/// </summary>
class SystemTimer : MonoBehaviour
{
//----------------------------------------------------------------------------
// 时间获取
//----------------------------------------------------------------------------
/// <summary>
/// 获得系统的时间,用long表示(0.00000001秒)
/// </summary>
/// <returns></returns>
public static long GetSysTime()
{
return DateTime.UtcNow.ToFileTimeUtc();
}
/// <summary>
/// 获得前后时间差(秒)
/// </summary>
public static float GetTimeSpanSeconds(DateTime timeBefore, DateTime timeAfter)
{
TimeSpan span = timeAfter - timeBefore;
return (int)span.TotalSeconds;
}
/// <summary>
/// 获得前后时间差(秒)
/// </summary>
/// <param name="timeAfter">如果无传入此值,或小于0,则取系统时间</param>
public static float GetTimeSpanSeconds(long timeBefore, long timeAfter = -1)
{
//FileTimeUtc将生成的是1秒=10,000,000纳秒,以1601年为起始点计时;
//(time1/3600/10000000/24/365)+1601)
if (timeAfter <= 0)
{
timeAfter = GetSysTime();
}
double delta = ((double)timeAfter - timeBefore) / 10000000;
return (float)delta;
}
/// <summary>
/// 将float秒的时间向上取整,再转为00:00:00格式
/// </summary>
/// <param name="fValue">秒</param>
/// <returns></returns>
public static string TimeToStr(float fValue)
{
int value = (int)Mathf.Ceil(fValue);
int hours = value / 3600;
value = value % 3600;
int min = value / 60;
value = value % 60;
int secs = value;
return string.Format(
"{0}:{1}:{2}",
hours.ToString("00"),
min.ToString("00"),
secs.ToString("00")
);
}
/// <summary>
/// 将00:00:00的字符串转为int时间(秒)
/// </summary>
/// <returns>返回秒为单位的时间</returns>
public static int StrToTime(string str)
{
string[] timeStrs = str.Split(':');
int hours, mins, secs;
int.TryParse(timeStrs[0], out hours);
int.TryParse(timeStrs[1], out mins);
int.TryParse(timeStrs[2], out secs);
int result = hours * 3600 + mins * 60 + secs;
return result;
}
//----------------------------------------------------------------------------
// 计时器部分
//----------------------------------------------------------------------------
/// <summary>
/// The delegater for coroutine
/// </summary>
static SystemTimer _instance;
/// <summary>
/// 所有定时器都停止与否
/// </summary>
static bool isAllTimmerStop = false;
/// <summary>
/// 所有的定时器,包括一个全局定时器
/// </summary>
/// <remarks>对于第0个Timer,将用作全局Timer,每个指定Tick会回调所有要监听全局时钟的方法</remarks>
List<TimerInfo> m_timers = new List<TimerInfo>();
/// <summary>
/// 全局的Timer,可用于同步通知所有需要协同一个时间点的方法
/// <para>如模拟每天时间流逝,则要用到GlobalTimer。</para>
/// <remarks> 一般情况下,globalTimer视作普通TimerInfo,在Update中被调用</remarks>
/// </summary>
GlobalTimerInfo m_refGlobalTimer;
/// <summary>
/// 是否允许
/// </summary>
public static bool IsTimerStop { get { return isAllTimmerStop; } }
/// <summary>
/// 单例
/// </summary>
static SystemTimer g_instance
{
get
{
if (_instance == null)
{
_instance = new GameObject("CoroutineDelegater").AddComponent<SystemTimer>();
//生成全局共用的Timer
var glTimer = new GlobalTimerInfo()
{
tickTockTime = 1, //-- 默认一秒Tick 一次
callOnce = false, //-- 一直Tick
};
_instance.m_refGlobalTimer = glTimer;
_instance.m_timers.Add(glTimer); //GlobalTimer视作普通Timer传入Timers中
}
return _instance;
}
}
/// <summary>
/// 设置所有Timmer停止与否
/// </summary>
/// <param name="isStop">If set to <c>true</c> is stop.</param>
public static void SetAllTimerStop(bool isStop)
{
isAllTimmerStop = isStop;
}
/// <summary>
/// 设置一个延迟动作,(无需Mono类) Sets the action after.
/// </summary>
public static void SetDelayTimer(System.Action cbAction, float timeDelta)
{
GameObjFunc.AssetNotNull(cbAction);
g_instance.m_timers.Add(new TimerInfo()
{
callbackFunc = cbAction,
tickTockTime = timeDelta,
timeLeft = timeDelta,
callOnce = true,
});
}
/// <summary>
/// 设置全局的Timer的Tick时间
/// </summary>
/// <param name="tickTime"></param>
public static void SetGlobalTimerTick(float tickTime)
{
g_instance.m_refGlobalTimer.tickTockTime = tickTime;
}
/// <summary>
/// 增加全局Timer的回调
/// </summary>
/// <param name="funcKey"></param>
/// <param name="callbackFunc"></param>
/// <returns></returns>
public static object AddOnGlobalTimerTick(object funcKey, System.Action callbackFunc)
{
g_instance.m_refGlobalTimer.AddCallback(funcKey, callbackFunc);
return funcKey;
}
[System.Obsolete("DO NOT USE THIS FUNC without class instance, use AddOnGlobalTimerTick() instead", true)]
public static void AddListenerOnGlobalTick(System.Action callbackFunc)
{
g_instance.m_refGlobalTimer.callbackFunc += callbackFunc;
}
/// <summary>
/// 删掉某个在全局Timer上的回调
/// </summary>
/// <param name="funcKey"></param>
public static void RemoveOnGlobalTimerTick(object funcKey)
{
g_instance.m_refGlobalTimer.RemoveCallback(funcKey);
}
/// <summary>
/// 设置一个每间隔时间段更新的Timer
/// </summary>
/// <param name="cbUpdateAction">update action.</param>
/// <param name="timeDelta">Time delta.</param>
public static TimerInfo SetUpdateTimer(System.Action cbUpdateAction, float timeDelta)
{
GameObjFunc.AssetNotNull(cbUpdateAction);
var timer = new TimerInfo()
{
callbackFunc = cbUpdateAction,
tickTockTime = timeDelta,
timeLeft = timeDelta,
callOnce = false,
};
g_instance.m_timers.Add(timer);
//创建完成后,返回这个Timer
return timer;
}
/// <summary>
/// 删除某个单一的UpdateTimer,并返回删除成功与否
/// </summary>
/// <param name="timer"></param>
/// <returns></returns>
public static bool RemoveUpdateTimer(TimerInfo timer)
{
return g_instance.m_timers.Remove(timer);
}
float timePassed = 0;
const float eachUpdateTime = 0.25f;
private void Update()
{
if (isAllTimmerStop)
{
return;
}
timePassed += Time.deltaTime;
if (timePassed > eachUpdateTime)
{
TimerInfo timer = null;
//尝试遍历所有需要的Timmer,并对到时间的进行回调:
for (int i = 0; i < m_timers.Count; i++)
{
timer = m_timers[i];
timer.timeLeft -= timePassed;
if (timer.timeLeft < 0)
{
if (timer.callbackFunc != null)
{
timer.callbackFunc();
}
if (timer.callOnce)
{
m_timers.RemoveAt(i); //只调用一次的,已经完成使命,则直接删掉该位置的Timer
i--;
}
else
{
timer.timeLeft = timer.tickTockTime - (timePassed - eachUpdateTime);//Timer重新开始,但是由于帧时间可能超过了一点点,所以这里予以减去,补偿流掉的时间
}
}
}
timePassed -= eachUpdateTime;
}
}
/// <summary>
/// 关于定时器的信息
/// </summary>
public class TimerInfo
{
/// <summary>
/// 每次倒计时完成后的回调动作
/// </summary>
public System.Action callbackFunc;
/// <summary>
/// 是否完成后不再回调,将删除
/// </summary>
public bool callOnce;
/// <summary>
/// 倒计时时间
/// </summary>
public float tickTockTime;
/// <summary>
/// 还剩多少时间进行TickTock
/// </summary>
public float timeLeft;
}
/// <summary>
/// 存储了多个TimerInfo,且可同时调用、可删除某个类实例对应的TimerInfo
/// </summary>
class GlobalTimerInfo : TimerInfo
{
/// <summary>
/// 存储了多个TimerInfo,且可同时调用、可删除某个类实例对应的TimerInfo
/// </summary>
Dictionary<object, System.Action> m_cbsForObj = new Dictionary<object, Action>();
/// <summary>
/// 待添加的Callbacks:
/// </summary>
List<KeyValuePair<object, System.Action>> m_cbsToAdd = new List<KeyValuePair<object, Action>>();
/// <summary>
/// 待删除的Callback对应的Key值:
/// </summary>
List<object> m_cbsToRemove = new List<object>();
/// <summary>
/// .ctor:创建回调方法,调用需要统一回调的方法们
/// </summary>
public GlobalTimerInfo()
{
//其回调方法是无需修改的,直接创建为遍历所有存储的TimerInfo
this.callbackFunc =
() =>
{
//待添加的回调方法:
if (m_cbsToAdd.Count > 0)
{
for (int i = 0; i < m_cbsToAdd.Count; i++)
{
m_cbsForObj.Add(m_cbsToAdd[i].Key, m_cbsToAdd[i].Value);
}
m_cbsToAdd.Clear();
}
//待删除的回调方法:
if (m_cbsToRemove.Count > 0)
{
for (int i = 0; i < m_cbsToRemove.Count; i++)
{
m_cbsForObj.Remove(m_cbsToRemove[i]);
}
m_cbsToRemove.Clear();
}
if (m_cbsForObj.Count > 0)
{
foreach (var cbFunc in m_cbsForObj.Values)
{
if (cbFunc != null)
{
cbFunc();
}
}
}
};
}
/// <summary>
/// 添加回调
/// </summary>
/// <param name="key">可指定哪个实例需要的回调,或另行传入唯一id,调用者自行确保其唯一性</param>
/// <param name="callbackFunc">需要加入到全局Timer中的回调方法</param>
public void AddCallback(object key, System.Action callbackFunc)
{
m_cbsToAdd.Add(new KeyValuePair<object, Action>(key, callbackFunc));
}
/// <summary>
/// 删除回调
/// </summary>
/// <param name="key">可指定哪个实例需要的回调,或另行传入唯一id。需在Add中出现的</param>
public void RemoveCallback(object key)
{
m_cbsToRemove.Add(key);
}
}
}
此处可能存在不合适展示的内容,页面不予展示。您可通过相关编辑功能自查并修改。
如您确认内容无涉及 不当用语 / 纯广告导流 / 暴力 / 低俗色情 / 侵权 / 盗版 / 虚假 / 无价值内容或违法国家有关法律法规的内容,可点击提交进行申诉,我们将尽快为您处理。