Files
Main/Assets/Plugins/References/FuncellBase/Timer/GameTime/GameTimeManager.cs

272 lines
8.8 KiB
C#
Raw Normal View History

2025-01-25 04:38:09 +08:00
using System;
using System.Collections.Generic;
using UnityEngine;
using FLogger = UnityEngine.Gonbest.MagicCube.FLogger;
namespace Thousandto.Core.Base
{
/// <summary>
/// 游戏时间系统
/// </summary>
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<TimeAction> _actions = new List<TimeAction>();
//时间间隔计数处理
private List<TimeIntervalConter> _lstInterCounter = new List<TimeIntervalConter>();
#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
}
}