2024-08-23 15:49:34 +08:00

706 lines
21 KiB
C#
Raw 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.

//#define TRACK_PARTICLE
//#define TRACK_MODEL
using System;
using System.Collections;
using System.Collections.Generic;
using Games.Events;
using Games.GlobeDefine;
using Games.LogicObj;
using Games.Mission;
using Games.Scene;
using GCGame.Table;
using Module.Log;
using UnityEngine;
using UnityEngine.Events;
public class GameManager : MonoBehaviour
{
// 预期每30秒执行一次GC
public const float unloadInterval = 120f;
// // 本想使用异步回调, 但考虑到项目现有整体机制, 想了又想,还是先注释掉吧
// public delegate void InitDataFinishDelegate();
//
// public delegate void LoadRawDataFinishDelegate(byte[] bytes);
public static GameManager gameManager; //GameManager以单件形式存在
public ObjModelPool modelPool { get; private set; }
// 特效池也移动到永久资源区 - 否则预加载特效将失去意义
public CentralEffectPool effectPool { get; private set; }
public float nextUnloadTime { get; private set; }
/// <summary>
/// 是否游戏已经退出处理一些关闭时调用OnDestroy产生的报错
/// </summary>
public static bool applicationQuit
{
get
{
return AssetUpdateDownloaderTick.applicationQuit;
}
}
///// <summary>
///// 是否使用画质警告面板
///// </summary>
//public bool useGraphicsNotice { get; set; }
//隐身shader
//public static Shader m_ShaderForStealth;
//////////////////////////////////////////////////////////////////////////
//生活技能
//////////////////////////////////////////////////////////////////////////
private LiveSkill _LiveSkill;
//////////////////////////////////////////////////////////////////////////
//交易市场
//////////////////////////////////////////////////////////////////////////
private Market _Market;
//public InitDataFinishDelegate initDataCallback;
// /// <summary>
// /// 是否Android低端版。<= 512M || 双核
// /// </summary>
// public bool IsLowAndroid;
//////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////
//自动寻路数据
//////////////////////////////////////////////////////////////////////////
////游戏当前状态
//private GameDefine_Globe.GAMESTATUS m_GameStatus;
//public GameDefine_Globe.GAMESTATUS GameStatus
//{
// get { return m_GameStatus; }
// set { m_GameStatus = value; }
//}
//由于处于在线状态还是离线状态
//在线状态需要连接服务器
private bool m_bOnLineState = true;
//测试选项,是否显示主角服务器位置
// public int m_MaxErrorNum = 5; //最大容错次数
//////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////
//主角在游戏中一直存在的数据
//////////////////////////////////////////////////////////////////////////
public int m_RunningScene;
private int m_BeforeRunningScene;
//////////////////////////////////////////////////////////////////////////
//声音管理器
//////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////
// public LoadRawDataFinishDelegate rawDataCallback;
// public WWW rawWWW;
private string strRawPath = "";
public SceneLogic SceneLogic { get; set; }
public bool OnLineState
{
get { return m_bOnLineState; }
set { m_bOnLineState = value; }
}
public bool ShowMainPlayerServerTrace { get; set; }
///场景管理器,保存全局的场景相关信息
public ActiveScene ActiveScene { get; set; }
private SceneObjManager m_sceneObjManager;
public SceneObjManager mSceneObjManager
{
get
{
if (m_sceneObjManager == null)
m_sceneObjManager = new SceneObjManager();
return m_sceneObjManager;
}
}
///任务管理器
public MissionManager MissionManager { get; private set; }
public CircleMissionManager CircleMissionManager { get; private set; }
///读表器
public TableManager TableManager { get; private set; }
public SoundManager SoundManager { get; set; }
public NetManager NetManager { get; set; }
public PlayerData PlayerDataPool { get; set; }
public OtherPlayerData OtherPlayerData { get; set; }
public AutoSearchAgent AutoSearch { get; set; }
public int RunningScene
{
get { return m_RunningScene; }
set
{
if (m_RunningScene != value)
{
m_RunningScene = value;
EventDispatcher.Instance.Dispatch(EventId.SceneIdUpdate, m_RunningScene);
}
EventDispatcher.Instance.Dispatch(EventId.UpdateUpRightSceneLineInfo);
}
}
public LiveSkill LiveSkill
{
get
{
if (_LiveSkill == null)
_LiveSkill = new LiveSkill();
return _LiveSkill;
}
}
//public Market Market
//{
// get { return _Market ?? (_Market = new Market()); }
//}
//public int m_loadErrorNum = 0;
// Awake
private void Awake()
{
if (gameManager != null)
{
Destroy(gameObject);
gameObject.SetActive(false);
return;
}
ActiveScene = new ActiveScene();
MissionManager = new MissionManager();
CircleMissionManager = new CircleMissionManager();
TableManager = new TableManager();
PlayerDataPool = new PlayerData();
OtherPlayerData = new OtherPlayerData();
modelPool = new ObjModelPool();
effectPool = new CentralEffectPool(modelPool.root);
//为gameManager赋值所有的其他操作都要放在后面
if (null != gameManager)
Destroy(gameObject);
gameManager = this;
DontDestroyOnLoad(gameObject);
// LogModule.DelLogFile();
Screen.sleepTimeout = SleepTimeout.NeverSleep;
ItemCombine.ResetItemCombine();
}
// Use this for initialization
private void Start()
{
//m_loadErrorNum = 0;
//如果单机版
if (OnLineState == false)
InitGame();
//#if UNITY_ANDROID
// if (SystemInfo.systemMemorySize < 768 || SystemInfo.processorCount < 2) IsLowAndroid = true;
//#endif
EventDispatcher.Instance.Add(EventId.OpenLockCtr, OnLockCtrOpen);
PlayerPreferenceData.OtherPlayerHideMask.onValueUpdate += OnHideMaskUpdate;
}
// Update is called once per frame
private void Update()
{
//处理事件
Singleton<EventSystem>.GetInstance().UpdateDelayEventQueue();
//更新ActiveScene
if (null != ActiveScene) ActiveScene.Update();
if (Singleton<ObjManager>.Instance.MainPlayer != null)
SceneMovieManager.Instance.Update();
Singleton<SignPostManager>.Instance.Update();
// 更新技能cd数值和其他状态保证在其他逻辑之前
PlayerDataPool.UpdateOwnSkills();
if (PlayerDataPool.FellowContainer != null)
PlayerDataPool.FellowContainer.UpdateSkillCD();
//宝图
TresureItem.Instance.Update();
}
#if UNITY_EDITOR && (TRACK_PARTICLE || TRACK_MODEL)
private void OnGUI()
{
#if TRACK_MODEL
modelPool.ShowDebugGui();
#endif
#if TRACK_PARTICLE
effectPool.ShowDebugGui();
#endif
}
#endif
private void FixedUpdate()
{
//心跳
UpdateNetHeart();
UpdatePerNetInterval();
}
private void OnDestroy()
{
PlayerPreferenceData.OtherPlayerHideMask.onValueUpdate -= OnHideMaskUpdate;
EventDispatcher.Instance.Remove(EventId.OpenLockCtr, OnLockCtrOpen);
}
// 注ObjManager没有构造和析构驱动因此暂时由GameManager来驱动ObjManager的内部事件
private void OnHideMaskUpdate(int hideMask)
{
if (ObjManager.Instance != null && !LoadingWindow._IsLoadingScene)
ObjManager.Instance.UpdateHideMask(hideMask);
}
//玩家状态改变之后全局变量清理工作,为玩家重新上线做准备
//适用范围包括玩家掉线,切换角色,切换帐号
public void PlayerStateChange()
{
//清理PlayerDataPool
gameManager.PlayerDataPool.CleanUp();
//Clean Damage Board
WorldUIRoot.Instance.ClearDamageBoard();
//清理邮件缓存
MailData.CleanMailData();
// PushNotification.ClearPushNotificationInfo();
//SceneLogic.UninitCameraControl();
//if (SoundManager != null)
// SoundManager.DestroyAudioListener();
}
public void InitGame()
{
//if (!GlobeVar.s_FirstInitGame) return;
if (false == InitGlobeManager())
LogModule.ErrorLog("Init Globe Manager Failed");
//初始化全局管理器
SoundManager = gameObject.EnsureComponent<SoundManager>();
//测试
NetManager = gameObject.EnsureComponent<NetManager>();
//自动寻路代理
AutoSearch = gameObject.EnsureComponent<AutoSearchAgent>();
//初始化网络心跳
InitNetwork();
//默认进入Login状态
//GameStatus = GameDefine_Globe.GAMESTATUS.GAMESTATUS_LOGIN;
//设置为非第一次进入游戏
GlobeVar.s_FirstInitGame = false;
//从这里开始添加其他操作
// if (null != m_TableManager)
// {
// }
//加载隐身shader
//if (m_ShaderForStealth == null) m_ShaderForStealth = Shader.Find("Transparent/Diffuse");
}
/// <summary>
/// Unity内部UnloadUnusedAssets 加一个限制
/// </summary>
public void UnloadUnusedAssets(bool force = false)
{
if (CanUnloadUnusedAssets() || force)
{
nextUnloadTime = Time.realtimeSinceStartup + unloadInterval;
Resources.UnloadUnusedAssets();
}
}
public bool CanUnloadUnusedAssets()
{
return Time.realtimeSinceStartup > nextUnloadTime;
}
/// <summary>
/// 锁定界面开启的事件接收器
/// </summary>
private void OnLockCtrOpen(object args)
{
UnloadIdleItems();
}
/// <summary>
/// 清除当前流程中不使用,但是缓存的资源
/// </summary>
public void UnloadIdleItems()
{
if (modelPool != null)
modelPool.CleanUnusedPool(-1f);
if (effectPool != null)
effectPool.CleanUnusedPool(-1f);
// 清理其他资源
UIManager.Instance().UnLoadUIForce();
// 清理完成后执行Unity的清理
UnloadUnusedAssets(true);
}
//初始化全局管理器
private bool InitGlobeManager()
{
//var bRet = true;
////初始化Scene Manager
//if (null != m_ActiveScene)
//{
// bRet = m_ActiveScene.Init();
// if (bRet)
// {
// LogModule.DebugLog("InitSceneManager OK");
// }
// else
// {
// LogModule.DebugLog("InitSceneManager Failed");
// }
//}
//else
//{
// LogModule.DebugLog("New SceneManager Failed");
//}
//初始化EventSystem
Singleton<EventSystem>.GetInstance().Init();
return true;
}
#region network heartbeat
private float _nextPerSecondUpdate;
private static float m_IntervalTime = -1f; //网速检测间隔时间
private static readonly float m_NetDelayTime = 250f; //服务器250ms一次网络包处理
private static int _ConnectLostTryTimesConst = -1; //连续4次无响应判断为掉线
private static int _ConnectTipsTryTimesConst = -1; //连续2次无响应开始提示网络异常
private float _nextPerNetIntervalUpdate;
public float NetSpeed;
public float SendNetTime = -1;
public int _ConnectLostTryTimes;
public int _ConnectLostReTryTimes;
private void InitNetwork()
{
SendNetTime = -1;
}
private void UpdateNetHeart()
{
if (Time.unscaledTime > _nextPerSecondUpdate && ServerChooseController.Instance() == null)
{
_nextPerSecondUpdate = Time.unscaledTime + 1f;
ReqSyncServerTime();
}
}
private void ReqSyncServerTime()
{
if (RunningScene == (int) GameDefine_Globe.SCENE_DEFINE.SCENE_LOGIN)
return;
if (!NetWorkLogic.GetMe().CheckSocketState())
return;
var cgBeat = (CG_CONNECTED_HEARTBEAT) PacketDistributed.CreatePacket(MessageID.PACKET_CG_CONNECTED_HEARTBEAT);
cgBeat.SetIsresponse(1);
cgBeat.SendPacket();
}
/// <summary>
/// 主玩家网络状态
/// </summary>
/// <returns></returns>
private void UpdatePerNetInterval()
{
if (Time.time > _nextPerNetIntervalUpdate)
{
if (m_IntervalTime > 0)
_nextPerNetIntervalUpdate = Time.time + m_IntervalTime;
else
_nextPerNetIntervalUpdate = Time.time + 1;
if (SceneLogic == null)
return;
//登陆,加载场景不处理
if (RunningScene == (int) GameDefine_Globe.SCENE_DEFINE.SCENE_LOGIN
|| RunningScene == (int) GameDefine_Globe.SCENE_DEFINE.SCENE_LOADINGSCENE
|| LoadingWindow._IsLoadingScene)
{
SendNetTime = -1;
return;
}
if (m_IntervalTime < 0) m_IntervalTime = SystemParam.GetSystemParam_FLOAT(32);
if (_ConnectLostTryTimesConst < 0) _ConnectLostTryTimesConst = SystemParam.GetSystemParam_INT(34);
if (_ConnectTipsTryTimesConst < 0) _ConnectTipsTryTimesConst = SystemParam.GetSystemParam_INT(33);
//检查当前网络是否可用
if (NetWorkLogic.GetMe().GetConnectStautus() != NetWorkLogic.ConnectStatus.CONNECTED
|| Application.internetReachability == NetworkReachability.NotReachable) //网络不可达
{
NetSpeed = -1;
SendNetTime = -1;
SetNetSpeed();
return;
}
//说明网络延迟已经超过基本通信时间,直接网络差
if (SendNetTime > 0)
{
NetSpeed = 10000;
//SendNetTime = -1;
SetNetSpeed();
#if !UNITY_EDITOR
//判断为断开连接
if (NetWorkLogic.GetMe().GetConnectStautus() == NetWorkLogic.ConnectStatus.CONNECTED)
{
++_ConnectLostTryTimes;
if (_ConnectLostTryTimes >= _ConnectLostTryTimesConst)
{
SendNetTime = -1;
NetWorkLogic.GetMe().ConnectLost();
++_ConnectLostReTryTimes;
_ConnectLostTryTimes = -_ConnectLostReTryTimes;
}
else if (_ConnectLostTryTimes >= _ConnectTipsTryTimesConst)
{
//LoadingTips.ShowLoadingTips(LoadingTips.LoadTipType.Reconnect);
GUIData.AddNotifyData(StrDictionary.GetClientDictionaryString("#{4942}"));
}
}
SendNetTime = Time.time;
//向服务器发包
var packetPing = (CG_PING)PacketDistributed.CreatePacket(MessageID.PACKET_CG_PING);
packetPing.SetNoparam(0);
packetPing.SendPacket();
#endif
return;
}
SendNetTime = Time.time;
//向服务器发包
var cgPing = (CG_PING) PacketDistributed.CreatePacket(MessageID.PACKET_CG_PING);
cgPing.SetNoparam(0);
cgPing.SendPacket();
_ConnectLostReTryTimes = 0;
_ConnectLostTryTimes = 0;
}
}
public void SetPingNetSpeed()
{
//ping回应时立刻关闭loading
LoadingTips.HideLoadingTips();
//计算网络延迟时间
if (SendNetTime > 0)
{
NetSpeed = (Time.time - SendNetTime) * 1000 - m_NetDelayTime;
if (NetSpeed < 0)
NetSpeed = 0;
SendNetTime = -1;
}
if (PlayerFrameLogic.Instance() != null)
PlayerFrameLogic.Instance().GetWifiInfo(NetSpeed);
}
private void SetNetSpeed()
{
if (PlayerFrameLogic.Instance() != null)
PlayerFrameLogic.Instance().GetWifiInfo(NetSpeed);
}
#endregion
#region LateUpdate排序管理
// 排序记录
// 摇杆更新位置
public const int joyStickUpdateOrder = -12;
// ThirdPersonController更新操作
// public const int personControllerUpdateOrder = -11;
// ObjManager更新死亡Npc删除的时间
public const int deadNpcUpdateOrder = -20;
// 角色移动状态检测并发送移动指令
public const int playerMoveUpdateOrder = -10;
// 摄像机更新位置
public const int cameraControllerUpdateOrder = 0;
// NetworkLogic发送协议接受执行协议在Update周期
public const int networkLogicUpdateOrder = 100;
// 用于排序LateUpdate周期中各项更新指令的工具比如 摇杆Tick先于ThirdPersonController先于Move组件先于Move协议发送 这个顺序先于摄像机位置更新这个顺序
private static readonly List<MyTuple<int, UnityAction>> _lateUpdateList = new List<MyTuple<int, UnityAction>>();
public GameManager()
{
ShowMainPlayerServerTrace = false;
}
/// <summary>
/// 注册需要排序的LateUpdate指令。注摄像机更新order = 0网络协议发送order = 100
/// </summary>
public static void AddLateUpdate(UnityAction function, int order)
{
var record = _lateUpdateList.Find(a => a.first == order);
if (record == null)
{
record = new MyTuple<int, UnityAction> {first = order, second = function};
_lateUpdateList.Add(record);
_lateUpdateList.Sort((a, b) => a.first.CompareTo(b.first));
}
else
{
record.second += function;
}
}
public static void RemoveLateUpdate(UnityAction function, int order)
{
var index = _lateUpdateList.FindIndex(a => a.first == order);
if (index >= 0)
_lateUpdateList[index].second -= function;
// if (_lateUpdateList[index].second == null)
// _lateUpdateList.RemoveAt(index);
}
private void LateUpdate()
{
for (var i = 0; i < _lateUpdateList.Count; i++)
if (_lateUpdateList[i].second != null)
try
{
_lateUpdateList[i].second.Invoke();
}
catch (Exception e)
{
LogModule.ErrorLog(e.ToString());
}
}
#endregion
#region
/// <summary>
/// 延迟恢复收发服务器协议
/// </summary>
public void RecoverNetDelay(float delay)
{
StartCoroutine(RecoverNetCoroutine(delay));
}
public IEnumerator RecoverNetCoroutine(float delay)
{
yield return new WaitForSeconds(delay);
RecoverNet();
}
/// <summary>
/// 恢复收发服务器协议
/// </summary>
public void RecoverNet()
{
//设置是否可处理消息包
NetWorkLogic.GetMe().CanProcessPacket = true;
if (RunningScene != (int) GameDefine_Globe.SCENE_DEFINE.SCENE_LOGIN)
{
var packet = (CG_ENTER_SCENE_OK) PacketDistributed.CreatePacket(MessageID.PACKET_CG_ENTER_SCENE_OK);
packet.IsOK = 1;
packet.SendPacket();
LogModule.DebugLog("CG_ENTER_SCENE_OK ...");
}
}
#endregion
//public void GetRawData(string strPath)
//{
// m_loadErrorNum++;
// strRawPath = strPath;
//
// StartCoroutine(GetWWWRawData());
//}
//public IEnumerator GetWWWRawData()
//{
// rawWWW = new WWW(strRawPath);
// yield return rawWWW;
//
// bool isError = string.IsNullOrEmpty(rawWWW.error);
// if (!isError)
// {
// //LogModule.DebugLog("Raw Data WWW Error" + rawWWW.url);
// //资源加载过程中发生错误。结束本次资源加载,重新请求资源加载。
//
// rawWWW.Dispose();
// rawWWW = null;
//
// if (m_loadErrorNum > m_MaxErrorNum)
// {
// rawDataCallback(null);
// initDataCallback();
// }
// else
// {
// if (ActiveScene != null)
// {
// //SetTerrainData
// ActiveScene.SetTerrainData();
// }
// }
// }
// else
// {
// rawDataCallback(rawWWW.bytes);
// initDataCallback();
// }
//}
}