//#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();
// }
//}
}