Files
2025-01-25 04:38:09 +08:00

272 lines
8.8 KiB
C#
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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
}
}