using UnityEngine;
|
using System.Collections;
|
using UnityEngine.Events;
|
using UnityEngine.SceneManagement;
|
using System;
|
using Snxxz.UI;
|
using TableConfig;
|
|
[XLua.LuaCallCSharp]
|
public class StageManager : Singleton<StageManager>
|
|
{
|
private Stage m_CurrentStage;
|
|
private Stage.E_StageType m_StageType;
|
|
public UnityAction onStageLoadFinish;
|
public event Action<int> onStartStageLoadingEvent;
|
public event Action<float> loadingProgressEvent;
|
|
bool m_IsServerPreparing = false;
|
public bool isServerPreparing {
|
get { return m_IsServerPreparing; }
|
set { m_IsServerPreparing = value; }
|
}
|
|
public Stage.E_StageType StageType {
|
get {
|
return m_StageType;
|
}
|
}
|
|
public Stage CurrentStage {
|
get {
|
return m_CurrentStage;
|
}
|
}
|
|
int m_CurrentMapId;
|
public int currentMapId {
|
get { return m_CurrentMapId; }
|
private set { m_CurrentMapId = value; }
|
}
|
|
int m_CurrentMapResID;
|
public int currentMapResId {
|
get {
|
return m_CurrentMapResID;
|
}
|
private set { m_CurrentMapResID = value; }
|
}
|
|
string m_StageAssetName;
|
public string stageAssetName { get { return m_StageAssetName; } }
|
|
|
float m_LoadingProgress = 0f;
|
float loadingProgress {
|
get { return m_LoadingProgress; }
|
set {
|
m_LoadingProgress = value;
|
if (loadingProgressEvent != null)
|
{
|
loadingProgressEvent(Mathf.Clamp01(m_LoadingProgress));
|
}
|
}
|
}
|
|
public bool isLoading { get; private set; }
|
|
StageLoadTimeOutCatcher loadTimeOutCatcher;
|
|
public StageManager()
|
{
|
DebugEx.LogFormat("初始化StageManager");
|
}
|
|
public void Load<T>(int stageId) where T : Stage
|
{
|
|
loadTimeOutCatcher = StageLoadTimeOutCatcher.Begin(stageId);
|
|
// 读取配置的方式创建场景
|
var mapResConfig = DTCA127_tagMCStartChangeMap.GetMapResourcesConfig();
|
|
if (AssetSource.sceneFromEditor || AssetVersionUtility.unPriorAssetDownLoadDone)
|
{
|
SnxxzGame.Instance.StartCoroutine(LoadCoroutine<T>(stageId, mapResConfig.ID, mapResConfig.MapResources, true));
|
}
|
else
|
{
|
var assetVersion = AssetVersionUtility.GetAssetVersion(StringUtility.Contact("maps/", mapResConfig.MapResources.ToLower()));
|
if (assetVersion != null && assetVersion.IsPriorAsset())
|
{
|
SnxxzGame.Instance.StartCoroutine(LoadCoroutine<T>(stageId, mapResConfig.ID, mapResConfig.MapResources, true));
|
}
|
else
|
{
|
SnxxzGame.Instance.StartCoroutine(BackToNoviceVillageWhileMapResourceLacked(mapResConfig.ID));
|
}
|
}
|
}
|
|
public void LoadCreateRoleStage()
|
{
|
SnxxzGame.Instance.StartCoroutine(LoadCoroutine<CreateRoleStage>(2, 0, "CreateRole_001", false));
|
}
|
|
public void LoadSelectRoleStage()
|
{
|
SnxxzGame.Instance.StartCoroutine(LoadCoroutine<SelectRoleStage>(2, 0, "CreateRole_001", false));
|
}
|
|
public void LoadLoginStage()
|
{
|
if (PlayerDatas.Instance.hero != null)
|
{
|
GAMgr.Instance.ServerDie(PlayerDatas.Instance.hero.ServerInstID);
|
GAMgr.Instance.Release(PlayerDatas.Instance.hero);
|
PlayerDatas.Instance.hero = null;
|
}
|
SnxxzGame.Instance.StartCoroutine(LoadCoroutine<LoginStage>(1, 0, "Level_Login", false));
|
}
|
|
IEnumerator LoadCoroutine<T>(int _stageId, int mapResConfigID, string _resources, bool _needEmpty) where T : Stage
|
{
|
if (currentMapResId != 0 && currentMapResId == mapResConfigID)
|
{
|
#if UNITY_EDITOR
|
Debug.LogFormat("StageManager出现加载相同地图行为:" + mapResConfigID);
|
#endif
|
|
if (loadTimeOutCatcher != null)
|
{
|
loadTimeOutCatcher.Stop();
|
loadTimeOutCatcher = null;
|
}
|
ExceptionCatcher.ReportException("场景加载 Step1", StringUtility.Contact("StageManager出现加载相同地图行为:", mapResConfigID));
|
yield break;
|
}
|
|
isLoading = true;
|
Application.backgroundLoadingPriority = ThreadPriority.High;
|
try
|
{
|
if (onStartStageLoadingEvent != null)
|
{
|
onStartStageLoadingEvent(currentMapId);
|
}
|
}
|
catch (Exception ex)
|
{
|
Debug.LogError("场景加载开始事件发生异常:" + ex);
|
ExceptionCatcher.ReportException("场景加载 Step2", ex);
|
}
|
|
var progressBuf = loadingProgress = 0f;
|
var timer = 0f;
|
var duration = 1f;
|
|
var lastCurrentMapResId = currentMapResId;
|
var lastMapId = currentMapId;
|
currentMapResId = mapResConfigID;
|
currentMapId = _stageId;
|
m_StageAssetName = _resources;
|
|
SystemSetting.Instance.LetFPSUnLimit();
|
|
try
|
{
|
WindowCenter.Instance.asyncLoad.StopAllTasks();
|
//为什么在这个地方要调用两次关闭其他窗口的接口呢,这个水就深了。
|
//因为有些界面被关闭的时候,会去打开主界面,所以,还得再关闭一次关闭其他窗口的界面,防止主界面被意外开启。
|
switch (_stageId)
|
{
|
case 2:
|
WindowCenter.Instance.DestoryWinsByStage(WindowCenter.WindowStage.Login);
|
WindowCenter.Instance.CloseOthers<LaunchBackGroundWin>();
|
if (!WindowCenter.Instance.IsOpen<LaunchBackGroundWin>())
|
{
|
WindowCenter.Instance.Open<LaunchBackGroundWin>(true);
|
}
|
|
WindowCenter.Instance.CloseOthers<LaunchBackGroundWin>();
|
break;
|
case 1:
|
WindowCenter.Instance.DestoryWinsByStage(WindowCenter.WindowStage.Launch);
|
WindowCenter.Instance.CloseOthers<LaunchBackGroundWin>();
|
if (!WindowCenter.Instance.IsOpen<LaunchBackGroundWin>())
|
{
|
WindowCenter.Instance.Open<LaunchBackGroundWin>(true);
|
}
|
|
WindowCenter.Instance.CloseOthers<LaunchBackGroundWin>();
|
break;
|
default:
|
WindowCenter.Instance.DestoryWinsByStage(WindowCenter.WindowStage.SelectRole);
|
WindowCenter.Instance.CloseOthers<LoadingWin>();
|
if (!WindowCenter.Instance.IsOpen<LoadingWin>())
|
{
|
LoadingWin.targetMapResId = currentMapResId;
|
WindowCenter.Instance.Open<LoadingWin>(true);
|
}
|
|
WindowCenter.Instance.CloseOthers<LoadingWin>();
|
break;
|
}
|
}
|
catch (System.Exception ex)
|
{
|
ExceptionCatcher.ReportException("场景加载 Step3", ex);
|
}
|
|
loadingProgress += 0.05f;
|
// 存在当前场景则进行卸载
|
if (CurrentStage != null)
|
{
|
CurrentStage.UnInitialize();
|
}
|
////////////////////////////////////////////////////////////////////////////////////////////
|
// 加载一个空的场景,用以卸载掉之前场景的对象,再加载新的场景,防止2个场景的对象内存占用过多
|
// 同步加载的方法
|
|
if (_needEmpty)
|
{
|
SceneManager.LoadScene("Empty");
|
}
|
|
var unloadUnUsedOperation = Resources.UnloadUnusedAssets();
|
while (!unloadUnUsedOperation.isDone)
|
{
|
yield return null;
|
}
|
|
loadingProgress += 0.05f;
|
GC.Collect();
|
loadingProgress += 0.1f;
|
|
try
|
{
|
if (!AssetSource.sceneFromEditor)
|
{
|
AssetBundleUtility.Instance.UnloadAssetBundle("maps/map000_xsdt", true, false);
|
AssetBundleUtility.Instance.UnloadAssetBundle(GetAssetBundleNameByStageId(lastMapId, lastCurrentMapResId), true, false);
|
AssetBundleUtility.Instance.Sync_LoadAll(GetAssetBundleNameByStageId(currentMapId, currentMapResId));
|
}
|
}
|
catch (System.Exception ex)
|
{
|
ExceptionCatcher.ReportException("场景加载 Step4", ex);
|
}
|
|
var sceneLoadOperation = SceneManager.LoadSceneAsync(_resources);
|
progressBuf = loadingProgress;
|
timer = 0f;
|
duration = 1f;
|
while (!sceneLoadOperation.isDone)
|
{
|
timer += Time.deltaTime;
|
loadingProgress = Mathf.Clamp(progressBuf + timer / duration * 0.6f, progressBuf, progressBuf + 0.6f);
|
yield return null;
|
}
|
|
if (_stageId == 10010)
|
{
|
while (!PreFightMission.Instance.IsHandleMissionState)
|
{
|
yield return null;
|
}
|
|
try
|
{
|
// 如果用户尚未完成前期战斗部分
|
if (!PreFightMission.Instance.IsFinished())
|
{
|
if (!AssetSource.sceneFromEditor)
|
{
|
AssetBundleUtility.Instance.Sync_LoadAll("maps/map000_xsdt");
|
}
|
SceneManager.LoadScene("Map000_Xsdt", LoadSceneMode.Additive);
|
}
|
}
|
catch (System.Exception ex)
|
{
|
ExceptionCatcher.ReportException("场景加载 Step5", ex);
|
}
|
}
|
|
yield return null;
|
loadingProgress = loadingProgress + 0.1f;
|
|
// 场景加载完就可以确定玩家位置了, 不需要等待具体场景的逻辑初始化
|
if (_stageId > 2)
|
{
|
try
|
{
|
InitHero();
|
}
|
catch (System.Exception ex)
|
{
|
ExceptionCatcher.ReportException("场景加载 Step6", ex);
|
}
|
}
|
|
try
|
{
|
GameObject _gameObject = new GameObject(string.Format("__Stage_{0}_", _resources));
|
m_CurrentStage = _gameObject.AddComponent<T>();
|
m_StageType = m_CurrentStage is DungeonStage ? Stage.E_StageType.Dungeon : Stage.E_StageType.MainCity;
|
m_CurrentStage.mapId = _stageId;
|
}
|
catch (System.Exception ex)
|
{
|
ExceptionCatcher.ReportException("场景加载 Step7", ex);
|
}
|
|
yield return null;
|
|
loadingProgress += 0.1f;
|
|
// 由于0401包只是通知服务端开始加载地图, 并不表示已经加载完毕
|
// 客户端由0401开始加载地图, 可能存在客户端加载完毕但是服务端还没准备好的情况
|
// 所以针对副本地图需要在这里等待服务端0109回包才能发送此包
|
|
progressBuf = loadingProgress;
|
timer = 0f;
|
duration = 1f;
|
while (isServerPreparing)
|
{
|
timer += Time.deltaTime;
|
loadingProgress = Mathf.Clamp(progressBuf + timer / duration * 0.2f, progressBuf, progressBuf + 0.2f);
|
yield return null;
|
}
|
|
if (m_StageType == Stage.E_StageType.Dungeon)
|
{
|
var mapOk = new C0107_tagCInitMapOK();
|
mapOk.MapID = PlayerDatas.Instance.baseData.MapID;
|
mapOk.Type = 0;
|
GameNetSystem.Instance.SendInfo(mapOk);
|
}
|
else
|
{
|
Debug.LogFormat("不发包0107:当前Stage:{0}", CurrentStage);
|
}
|
|
isServerPreparing = false;
|
//如果是登录,那么要等待登录过程全部完成
|
while (m_StageType == Stage.E_StageType.Dungeon && DTC0403_tagPlayerLoginLoadOK.neverLoginOk)
|
{
|
yield return null;
|
}
|
|
loadingProgress = 1f;
|
|
try
|
{
|
if (onStageLoadFinish != null)
|
{
|
onStageLoadFinish();
|
}
|
}
|
catch (Exception ex)
|
{
|
Debug.LogError("场景加载完成事件发生异常:" + ex);
|
ExceptionCatcher.ReportException("场景加载 Step8", ex);
|
}
|
|
if (loadTimeOutCatcher != null)
|
{
|
loadTimeOutCatcher.Stop();
|
}
|
loadTimeOutCatcher = null;
|
|
Application.backgroundLoadingPriority = ThreadPriority.BelowNormal;
|
isLoading = false;
|
|
DebugEx.LogFormat("StageManager => Load Scene : {0} Finished.", _resources);
|
WindowCenter.Instance.Close<LoadingWin>();
|
SystemSetting.Instance.SetGameFps(SystemSetting.Instance.GetGameFps());
|
|
}
|
|
IEnumerator BackToNoviceVillageWhileMapResourceLacked(int _mapResId)
|
{
|
currentMapResId = _mapResId;
|
LoadingWin.targetMapResId = 1;
|
WindowCenter.Instance.Open<LoadingWin>(true);
|
|
while (isServerPreparing)
|
{
|
yield return null;
|
}
|
|
var mapOk = new C0107_tagCInitMapOK();
|
mapOk.MapID = PlayerDatas.Instance.baseData.MapID;
|
mapOk.Type = 0;
|
GameNetSystem.Instance.SendInfo(mapOk);
|
|
//如果是登录,那么要等待登录过程全部完成
|
while (m_StageType == Stage.E_StageType.Dungeon && DTC0403_tagPlayerLoginLoadOK.neverLoginOk)
|
{
|
yield return null;
|
}
|
|
yield return WaitingForSecondConst.WaitMS1000;
|
|
var mapConfig = Config.Instance.Get<MapConfig>(PlayerDatas.Instance.baseData.MapID);
|
if (mapConfig.MapFBType == (int)MapType.OpenCountry)
|
{
|
var sjzMapConfig = Config.Instance.Get<MapConfig>(10010);
|
var position = new Vector3(sjzMapConfig.BornPoints[0].x, 0, sjzMapConfig.BornPoints[0].y);
|
MapTransferUtility.Send_WorldTransfer(10010, position, MapTransferType.WorldTransport, 255, 0);
|
}
|
else
|
{
|
ModelCenter.Instance.GetModel<DungeonModel>().ExitCurrentDungeon();
|
}
|
|
if (loadTimeOutCatcher != null)
|
{
|
loadTimeOutCatcher.Stop();
|
}
|
loadTimeOutCatcher = null;
|
}
|
|
private void InitHero()
|
{
|
|
// 初始化摄像机
|
if (!CameraController.Instance)
|
{
|
UnityEngine.Object.Instantiate(Resources.Load<GameObject>("Prefabs/GameCamera"));
|
CameraController.Instance.AcceptInput = false;
|
CameraController.Instance.CameraObject.enabled = false;
|
}
|
|
GA_Hero _hero = PlayerDatas.Instance.hero;
|
if (_hero == null)
|
{
|
_hero = GAMgr.Instance.RequestPlayer<GA_Hero>(PlayerDatas.Instance.PlayerId, E_ActorGroup.User, null);
|
}
|
|
_hero.State = E_ActorState.Idle;
|
_hero.ActorInfo.ResetHp((int)PlayerDatas.Instance.baseData.HP, -1, (int)PlayerDatas.Instance.baseData.HP);
|
_hero.CalculateMoveSpeed((ushort)PlayerDatas.Instance.extersion.SpeedValue);
|
_hero.CalculateAtkSpeed(PlayerDatas.Instance.extersion.battleValEx1);
|
_hero.InitBornPos(PlayerDatas.Instance.baseData.PosX, PlayerDatas.Instance.baseData.PosY);
|
|
CameraController.Instance.SetLookTarget(_hero.Root);
|
CameraController.Instance.Apply();
|
|
PlayerPackModel _packModel = ModelCenter.Instance.GetModel<PlayerPackModel>();
|
SinglePackModel _equipModel = _packModel.GetSinglePackModel(PackType.rptEquip);
|
|
byte _suitLevel = 0;
|
ItemModel _itemModel = _equipModel.GetItemModelByIndex((int)RoleEquipType.retClothes);
|
|
if (_itemModel != null)
|
{
|
if (_itemModel.itemInfo.IsSuite == 1)
|
{
|
_suitLevel = (byte)_itemModel.useDataDict[30][0];
|
}
|
|
_hero.SwitchClothes((uint)_itemModel.itemInfo.ItemID);
|
_hero.ChangeEquip((int)RoleEquipType.retClothes, (uint)_itemModel.itemInfo.ItemID, _suitLevel);
|
}
|
else
|
{
|
_hero.SwitchClothes(0);
|
}
|
|
_itemModel = _equipModel.GetItemModelByIndex((int)RoleEquipType.retWeapon);
|
|
if (_itemModel != null)
|
{
|
_hero.SwitchWeapon((uint)_itemModel.itemInfo.ItemID);
|
}
|
else
|
{
|
_hero.SwitchWeapon(0);
|
}
|
|
_itemModel = _equipModel.GetItemModelByIndex((int)RoleEquipType.retWeapon2);
|
|
if (_itemModel != null)
|
{
|
_hero.SwitchSecondary((uint)_itemModel.itemInfo.ItemID);
|
}
|
else
|
{
|
_hero.SwitchSecondary(0);
|
}
|
|
_itemModel = _equipModel.GetItemModelByIndex((int)RoleEquipType.retWing);
|
|
if (_itemModel != null)
|
{
|
_hero.SwitchWing((uint)_itemModel.itemInfo.ItemID);
|
}
|
|
_itemModel = _equipModel.GetItemModelByIndex((int)RoleEquipType.mount);
|
|
if (_itemModel != null)
|
{
|
PlayerMountDatas _mountModel = ModelCenter.Instance.GetModel<PlayerMountDatas>();
|
if (_mountModel.HorseRidingBool)
|
{
|
_hero.OnHorse(1);
|
}
|
}
|
|
_itemModel = _equipModel.GetItemModelByIndex((int)RoleEquipType.retSpiritAnimal);
|
|
if (_itemModel != null)
|
{
|
_hero.SwitchGuard((uint)_itemModel.itemInfo.ItemID);
|
}
|
|
_itemModel = _equipModel.GetItemModelByIndex((int)RoleEquipType.retHat);
|
if (_itemModel != null)
|
{
|
if (_itemModel.itemInfo.IsSuite == 1)
|
{
|
_suitLevel = (byte)_itemModel.useDataDict[30][0];
|
_hero.ChangeEquip((int)RoleEquipType.retHat, (uint)_itemModel.itemInfo.ItemID, _suitLevel);
|
}
|
}
|
|
_itemModel = _equipModel.GetItemModelByIndex((int)RoleEquipType.retBelt);
|
if (_itemModel != null)
|
{
|
if (_itemModel.itemInfo.IsSuite == 1)
|
{
|
_suitLevel = (byte)_itemModel.useDataDict[30][0];
|
_hero.ChangeEquip((int)RoleEquipType.retBelt, (uint)_itemModel.itemInfo.ItemID, _suitLevel);
|
}
|
}
|
|
_itemModel = _equipModel.GetItemModelByIndex((int)RoleEquipType.retShoes);
|
if (_itemModel != null)
|
{
|
if (_itemModel.itemInfo.IsSuite == 1)
|
{
|
_suitLevel = (byte)_itemModel.useDataDict[30][0];
|
_hero.ChangeEquip((int)RoleEquipType.retShoes, (uint)_itemModel.itemInfo.ItemID, _suitLevel);
|
}
|
}
|
|
_itemModel = _equipModel.GetItemModelByIndex((int)RoleEquipType.retTrousers);
|
if (_itemModel != null)
|
{
|
if (_itemModel.itemInfo.IsSuite == 1)
|
{
|
_suitLevel = (byte)_itemModel.useDataDict[30][0];
|
_hero.ChangeEquip((int)RoleEquipType.retTrousers, (uint)_itemModel.itemInfo.ItemID, _suitLevel);
|
}
|
}
|
|
_hero.IdleImmediate();
|
|
_hero.SetFairyLeagueHeadUp(PlayerDatas.Instance.baseData.MapID == FairyLeagueModel.FAIRY_LEAGUE_DUNGEON);
|
_hero.CheckAncientHeadUp();
|
var titleId = 0;
|
if (PlayerDatas.Instance.baseData.MapID != 31160)
|
{
|
var titelModel = ModelCenter.Instance.GetModel<TitleModel>();
|
var title = titelModel.GetTitleEquip();
|
titleId = title != null && titelModel.IsTitleGain(title.id) ? title.id : 0;
|
}
|
_hero.SwitchTitle((uint)titleId);
|
|
// 判断buff
|
if (StatusMgr.Instance.IsExist(PlayerDatas.Instance.PlayerId, StatusMgr.Instance.redNameBuffID))
|
{
|
_hero.SwitchRedName(true);
|
}
|
|
_hero.RequestLight();
|
|
PlayerDatas.Instance.hero = _hero;
|
}
|
|
private string GetAssetBundleNameByStageId(int stageID, int mapResID)
|
{
|
switch (stageID)
|
{
|
case 0:
|
return string.Empty;
|
case 1:
|
return "maps/level_login";
|
case 2:
|
return "maps/createrole_001";
|
default:
|
var mapResConfig = Config.Instance.Get<MapResourcesConfig>(mapResID);
|
if (mapResConfig != null)
|
{
|
return StringUtility.Contact("maps/", mapResConfig.MapResources);
|
}
|
return string.Empty;
|
}
|
|
}
|
|
}
|