//#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; } /// /// 是否游戏已经退出,处理一些关闭时调用OnDestroy产生的报错 /// public static bool applicationQuit { get { return AssetUpdateDownloaderTick.applicationQuit; } } ///// ///// 是否使用画质警告面板 ///// //public bool useGraphicsNotice { get; set; } //隐身shader //public static Shader m_ShaderForStealth; ////////////////////////////////////////////////////////////////////////// //生活技能 ////////////////////////////////////////////////////////////////////////// private LiveSkill _LiveSkill; ////////////////////////////////////////////////////////////////////////// //交易市场 ////////////////////////////////////////////////////////////////////////// private Market _Market; //public InitDataFinishDelegate initDataCallback; // /// // /// 是否Android低端版。<= 512M || 双核 // /// // 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.GetInstance().UpdateDelayEventQueue(); //更新ActiveScene if (null != ActiveScene) ActiveScene.Update(); if (Singleton.Instance.MainPlayer != null) SceneMovieManager.Instance.Update(); Singleton.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(); //测试 NetManager = gameObject.EnsureComponent(); //自动寻路代理 AutoSearch = gameObject.EnsureComponent(); //初始化网络心跳 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"); } /// /// Unity内部UnloadUnusedAssets 加一个限制 /// public void UnloadUnusedAssets(bool force = false) { if (CanUnloadUnusedAssets() || force) { nextUnloadTime = Time.realtimeSinceStartup + unloadInterval; Resources.UnloadUnusedAssets(); } } public bool CanUnloadUnusedAssets() { return Time.realtimeSinceStartup > nextUnloadTime; } /// /// 锁定界面开启的事件接收器 /// private void OnLockCtrOpen(object args) { UnloadIdleItems(); } /// /// 清除当前流程中不使用,但是缓存的资源 /// 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.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(); } /// /// 主玩家网络状态 /// /// 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> _lateUpdateList = new List>(); public GameManager() { ShowMainPlayerServerTrace = false; } /// /// 注册需要排序的LateUpdate指令。注:摄像机更新order = 0;网络协议发送order = 100; /// public static void AddLateUpdate(UnityAction function, int order) { var record = _lateUpdateList.Find(a => a.first == order); if (record == null) { record = new MyTuple {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 场景加载 /// /// 延迟恢复收发服务器协议 /// public void RecoverNetDelay(float delay) { StartCoroutine(RecoverNetCoroutine(delay)); } public IEnumerator RecoverNetCoroutine(float delay) { yield return new WaitForSeconds(delay); RecoverNet(); } /// /// 恢复收发服务器协议 /// 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(); // } //} }