using System; using System.Collections.Generic; using UnityEngine; using FLogger = UnityEngine.Gonbest.MagicCube.FLogger; namespace Thousandto.Core.Base { /// /// 游戏时间系统 /// public class GameTimeManager:BaseSystem { #region//静态属性变量 --单例模式 private static GameTimeManager _shareInstance = null; public static GameTimeManager ShareInstance { get { if (_shareInstance == null) { _shareInstance = new GameTimeManager(); } return _shareInstance; } } #endregion #region //私有成员变量 //最后一次同步的游戏时间 -- 单位秒 private ulong _lastGameTime = 0; //最后一次同步的系统时间 --- 单位秒 private ulong _lastSystemTime = 0; //总的秒数 private ulong _totalSecond = (ulong)(TimeConstDefine.BeginAt - DateTime.MinValue).TotalSeconds; //游戏开始时间 -- 单位毫秒 private long _gameStartTime = 0; //下一次tick时间 private float _nextTickTime = 0; //心跳时间间隔 private float _waitTickTime = 5; // 每5秒Tick一次 //时间活动处理 private List _actions = new List(); //时间间隔计数处理 private List _lstInterCounter = new List(); #endregion #region//属性信息 public float WaitTickTime { get { return _waitTickTime; } set { _waitTickTime = value; } } #endregion #region //构造函数 //游戏开始时间 public GameTimeManager() { Startup(); } #endregion #region //设置或者获取时间的函数 //游戏开始时间 public void Startup() { _gameStartTime = DateTime.Now.Ticks / TimeSpan.TicksPerMillisecond; _lastSystemTime = (ulong)Time.time; _lastGameTime = (ulong)(DateTime.Now.Ticks / TimeSpan.TicksPerSecond) - TimeConstDefine.DaysFrom; } //获取游戏运行时间的毫秒数 public Double GetNowTimeMillisecond() { return DateTime.Now.Ticks / TimeSpan.TicksPerMillisecond - _gameStartTime; } //当前时间 -- 秒数 public ulong CurrentTime { get { // 获取当前游戏时间(相对1970年的秒数) return _lastGameTime + (ulong)Time.time - _lastSystemTime; } set { // 同步时间(需要服务器时间校正) _lastGameTime = value - TimeConstDefine.DaysFrom; _lastSystemTime = (ulong)Time.time; } } // 获取当前游戏时间(绝对时间) -- 秒数 public ulong CurAbsoluteTime { get { return CurrentTime + _totalSecond; } } // 获取当前服务器时间(erlang和c#起始时间不一致) -- 秒数 public ulong CurServeTime { get { return CurrentTime + TimeConstDefine.DaysFrom; } } // 获取当前游戏时间 public DateTime CurrentDateTime { get { return SecondsToDateTime(CurrentTime); } } //以1970.1.1为基础增加一定秒数的到的日期时间值 public DateTime SecondsToDateTime(ulong seconds) { try { return TimeConstDefine.BeginAt.AddSeconds(seconds); } catch(Exception ex) { FLogger.LogException(ex); return DateTime.Now; } } #endregion #region//往心跳系统中增加时间间隔计数的对象 ////往心跳系统中增加时间间隔计数的对象 public TimeIntervalConter AddTimeIntervalConter(ulong beginTime, ulong intervalSeconds) { var tic = new TimeIntervalConter(beginTime,intervalSeconds); _lstInterCounter.Add(tic); return tic; } //移除间隔计数对象 public void RemoveTimeIntervalConter(TimeIntervalConter tic) { if (tic != null) { tic.Clear(); _lstInterCounter.Remove(tic); } } #endregion #region //往心跳系统添加TimeAction的方法 // 添加函数 时间格式为 time = "4:00:00" public void AddFunc(TimeActionType type, ulong setTime, MyAction action, string time) { if (action != null && time != null) { for (int i = _actions.Count - 1; i >= 0; i--) { if (_actions[i].type == type) { _actions.RemoveAt(i); } } TimeAction temp = new TimeAction(); temp.action = action; temp.timeStr = time; temp.type = type; temp.time = CheckTime(GetDifTime(time, setTime)) + CurrentTime; _actions.Add(temp); } } // 添加函数 时间格式为 time = "4:00:00" day 为周几更新 public void AddFunc(TimeActionType type, ulong setTime, MyAction action, string time, DayOfWeek day) { if (action != null && time != null) { for (int i = _actions.Count - 1; i >= 0; --i) { if (_actions[i].type == type) { _actions.RemoveAt(i); } } DateTime now = CurrentDateTime; DateTime startWeek = now.AddDays(1 - Convert.ToInt32(now.DayOfWeek.ToString("d"))); DateTime targetWeek = startWeek.AddDays((int)day == 0 ? 6 : (int)day); targetWeek.AddSeconds((ulong)(Convert.ToDateTime(time) - Convert.ToDateTime("0:00")).TotalSeconds); TimeAction temp = new TimeAction(); temp.action = action; temp.timeStr = time; temp.type = type; temp.time = (ulong)(targetWeek - now).TotalSeconds + CurrentTime; _actions.Add(temp); } } // 时间设置 public ulong CheckTime(double time, uint timeInterval = TimeConstDefine.OneDaySecond) { while (time < 0) { time += timeInterval; } return (ulong)time; } #endregion #region 游戏时间的心跳处理 protected override bool OnUpdate(float deltaTime) { if (Time.time > _nextTickTime) { _nextTickTime = Time.time + _waitTickTime; ulong currentTime = CurrentTime; for (int i = 0; i < _actions.Count; i++) { if (_actions[i].time <= currentTime) { _actions[i].action(); _actions[i].time += _actions[i].addTime; } if (_actions[i].type == TimeActionType.PartnerDay) { FLogger.DebugLogError(string.Format("距离更新还剩:{0}秒", _actions[i].time - currentTime)); } } //根据自定义的时间间隔进行触发一个GameTime消息 for (int i = 0; i < _lstInterCounter.Count; i++) { if (_lstInterCounter[i].m_beginTime <= currentTime) { _lstInterCounter[i].DoTickCallBack(); _lstInterCounter[i].m_beginTime += _lstInterCounter[i].m_intervalSeconds; } } } return true; } #endregion #region//私有方法 // 时间差量判断 (设置时间 - 当前时间) // 返回的是两个相差的秒数 // 如:当前4:00 设置为5:00:00 则返回3600秒 // 设置为3:00:00 则返回-3600秒 private long GetDifTime(string time, ulong second) { DateTime timeJudge = Convert.ToDateTime(time); DateTime timeNow = Convert.ToDateTime(TimeConstDefine.BeginAt.AddSeconds(second).ToLongTimeString()); return (long)(timeJudge - timeNow).TotalSeconds; } #endregion } }