447 lines
17 KiB
C#
447 lines
17 KiB
C#
using UnityEngine;
|
|
using System;
|
|
using System.Collections;
|
|
using Thousandto.Core.Base;
|
|
using Thousandto.Core.Asset;
|
|
using Thousandto.Code.Center;
|
|
using Thousandto.Cfg.Data;
|
|
using Thousandto.Core.Support;
|
|
using UnityEngine.SceneManagement;
|
|
using PathUtils = UnityEngine.Gonbest.MagicCube.PathUtils;
|
|
using CoroutinePool = UnityEngine.Gonbest.MagicCube.CoroutinePool;
|
|
using StringUtils = UnityEngine.Gonbest.MagicCube.StringUtils;
|
|
using FLogger = UnityEngine.Gonbest.MagicCube.FLogger;
|
|
|
|
namespace Thousandto.Code.Logic
|
|
{
|
|
/// <summary>
|
|
/// 场景加载类
|
|
/// </summary>
|
|
public class SceneLoadingState : GameStateBase
|
|
{
|
|
|
|
#region//当前变量
|
|
//状态转换控制设置
|
|
private LoadingState _loadingState = LoadingState.DEFAULT;
|
|
//加载参数
|
|
private LoadingArgs _loadingArgs = null;
|
|
//目标场景
|
|
private GameScene _targetScene = null;
|
|
#endregion
|
|
|
|
#region//属性信息
|
|
public GameScene TaregetScene
|
|
{
|
|
get
|
|
{
|
|
return _targetScene;
|
|
}
|
|
}
|
|
#endregion
|
|
|
|
#region//构造函数
|
|
public SceneLoadingState(GameStateId id) : base(id)
|
|
{ }
|
|
#endregion
|
|
|
|
protected override GameStateId OnGetStateID()
|
|
{
|
|
return GameStateId.SceneLoading;
|
|
}
|
|
|
|
protected override void OnEnter()
|
|
{
|
|
_loadingState = LoadingState.DEFAULT;
|
|
|
|
FrameMonitor.EndProfile();
|
|
|
|
//FLogger.LogError("Start Loading:"+Time.realtimeSinceStartup);
|
|
if (HardwareManager.MemoryInfo != null)
|
|
FLogger.LogTime(string.Format("SceneLoadingState Enter:AppUsed:{0},Free:{1}", HardwareManager.MemoryInfo.GetAppUsedMemory(), HardwareManager.MemoryInfo.GetFreeMemory()));
|
|
|
|
|
|
|
|
//0做输入检查,以及一些预处理
|
|
FLogger.DebugAssert(Arg != null, "SceneLoading OnEnter Arg is NULL");
|
|
|
|
_loadingArgs = Arg as LoadingArgs;
|
|
|
|
|
|
|
|
FLogger.DebugAssert(_loadingArgs != null, "SceneLoading Load param is invalid");
|
|
FLogger.DebugAssert(_loadingArgs.MapSetting != null, "SceneLoading MapSetting param is invalid");
|
|
|
|
if (_loadingArgs == null && _loadingArgs.MapSetting == null)
|
|
{
|
|
return;
|
|
}
|
|
|
|
//这里有判定的原因是,在选择界面和创建界面,根据玩家的一些基础信息已经对持久化资源进行了设置
|
|
if (_loadingArgs.FrontMapID != 0)
|
|
{
|
|
//设置一些不被清除的资源 -- 并且这里的时LocalPlayer也有可能还没有
|
|
GameCenter.GameSceneSystem.SetImmortalInfo(true);
|
|
}
|
|
|
|
//清除场景中的关联的预制
|
|
GameCenter.GameSceneSystem.SceneSweepPrefab();
|
|
|
|
//清除场景远近处理缓存
|
|
GameCenter.SceneRestoreSystem.ClearCache();
|
|
|
|
//只有窗体加载之后才会设置下一个场景
|
|
GameCenter.LuaSystem.Adaptor.OpenLoadingForm(() => {
|
|
//3.开始加载下一个场景的信息
|
|
_loadingState = LoadingState.CheckedUpdate;
|
|
});
|
|
|
|
}
|
|
|
|
protected override void OnLeave()
|
|
{
|
|
//_loadingArgs = null;
|
|
_loadingState = LoadingState.DEFAULT;
|
|
IGameState nextState = GameCenter.GameStateSystem.GetNextState();
|
|
if (nextState != null)
|
|
{
|
|
var next = nextState as GameStateBase;
|
|
if (next != null)
|
|
{
|
|
// 当登出或者重新登录时释放
|
|
IGameState state = GameCenter.GameStateSystem.GetCurState();
|
|
if (state != null)
|
|
{
|
|
if (next.GameStateID == GameStateId.Login ||
|
|
next.GameStateID == GameStateId.AppUpdateCheck)
|
|
{
|
|
FLogger.LogTime("OnLeave Next State" + next.GameStateID);
|
|
//1.处理声音
|
|
//2.处理UI
|
|
//3.发送退出游戏的消息
|
|
//4.释放数据
|
|
GameCenter.GameSceneSystem.StopBGMusic();
|
|
ReleaseData();
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
protected override bool OnUpdate(float deltaTime)
|
|
{
|
|
//计时器更新
|
|
GameCenter.TimerEventSystem.Update(deltaTime);
|
|
|
|
switch (_loadingState)
|
|
{
|
|
case LoadingState.CheckedUpdate: //判断更新
|
|
CheckUpdate();
|
|
break;
|
|
case LoadingState.StartImmortalPreLoad: //开始对持久资源进行预加载处理
|
|
ResourcesEx.IsPreLoadState = true;
|
|
if (_loadingArgs.FrontMapID <= 0)
|
|
{
|
|
_loadingState = LoadingState.ImmortalPreLoading;
|
|
FLogger.LogTime("ImmortalPreLoading");
|
|
//只有选择或创建角色后才会预加载
|
|
GameCenter.ImmortalResSystem.StartPreLoadImmort();
|
|
}
|
|
_loadingState = LoadingState.StartScenePreLoad;
|
|
break;
|
|
case LoadingState.ImmortalPreLoading: //正在进行对持久资源进行预加载
|
|
if (Time.frameCount % 30 == 0)
|
|
{
|
|
ImmortalLoading();
|
|
}
|
|
break;
|
|
case LoadingState.StartScenePreLoad: //开始场景的预加载处理
|
|
ResourcesEx.IsPreLoadState = false;
|
|
StartScenePreLoad();
|
|
break;
|
|
case LoadingState.EndLoading: //加载完毕
|
|
_loadingState = LoadingState.DEFAULT;
|
|
break;
|
|
}
|
|
return true;
|
|
}
|
|
|
|
#region//判断更新
|
|
//判断是否进行分段更新
|
|
private void CheckUpdate()
|
|
{
|
|
//if (PathUtils.IsStreaming())
|
|
//{
|
|
// FLogger.LogTime("CheckUpdate");
|
|
// //绝对路径,如果不存在,则做分段更新操作
|
|
// string filePath = PathUtils.GetStreamingRootPath("/Assets/GameAssets/Resources/Scene/" + _loadingArgs.MapSetting.LevelName + ".unity3d");
|
|
// if (!System.IO.File.Exists(filePath) )
|
|
// {
|
|
// UnityEngine.Debug.LogWarning("场景文件不存在,需要更新: " + filePath);
|
|
// _loadingState = LoadingState.CheckedUpdateWait;
|
|
// GameCenter.MsgPromptSystem.ShowMsgBox(DeclareMessageString.Get(DeclareMessageString.C_SCENE_LOADING_UPDATE_RES),
|
|
// DeclareMessageString.Get(DeclareMessageString.C_MSGBOX_CANCEL),
|
|
// DeclareMessageString.Get(DeclareMessageString.C_MSGBOX_OK),
|
|
// (_ret) =>
|
|
// {
|
|
// _loadingState = LoadingState.DEFAULT;
|
|
// if (_ret == MsgBoxResultCode.Button2)
|
|
// {
|
|
// GameCenter.GameSceneSystem.ReturnToUpdate();
|
|
// }
|
|
// else
|
|
// {
|
|
// GameCenter.GameSceneSystem.ReturnToLogin();
|
|
// }
|
|
// }
|
|
// );
|
|
|
|
// }
|
|
//}
|
|
//切换为加载状态
|
|
if (_loadingState == LoadingState.CheckedUpdate)
|
|
{
|
|
_loadingState = LoadingState.StartImmortalPreLoad;
|
|
}
|
|
}
|
|
|
|
//持久资源加载中
|
|
private void ImmortalLoading()
|
|
{
|
|
var sum = GameCenter.ImmortalResSystem.GetPreLoadSum();
|
|
if (sum == 0)
|
|
{
|
|
_loadingState = LoadingState.StartScenePreLoad;
|
|
}
|
|
else
|
|
{
|
|
var cur = GameCenter.ImmortalResSystem.GetPreLoadCurrentCount();
|
|
if (cur <= 0)
|
|
{
|
|
_loadingState = LoadingState.StartScenePreLoad;
|
|
}
|
|
else
|
|
{
|
|
GameCenter.LuaSystem.Adaptor.SetLoadingFormProgress(0.5f * ((float)cur / (float)sum));
|
|
}
|
|
}
|
|
}
|
|
|
|
//开始场景加载中
|
|
private void StartScenePreLoad()
|
|
{
|
|
FLogger.LogTime("StartScenePreLoad");
|
|
GameCenter.LuaSystem.Adaptor.SetLoadingFormProgress(0.5f);
|
|
_loadingState = LoadingState.ScenePreLoading;
|
|
//开始切换音乐
|
|
GameCenter.GameSceneSystem.PlayBGMusic(_loadingArgs.MapSetting.MapId);
|
|
|
|
//添加后台更新支持
|
|
GameCenter.UpdateSystem.CheckSceneResExist(_loadingArgs.MapSetting.MapId,
|
|
() =>
|
|
{
|
|
//开始加载场景
|
|
SceneRootAssetsLoader.LoadSceneAssets(
|
|
_loadingArgs.MapSetting.LevelName,
|
|
() =>
|
|
{
|
|
bool isLoadFail = ResourcesEx.DebugUIModel ? true : false;
|
|
if (!SceneRootAssetsLoader.CurrSceneBundleExit())
|
|
{
|
|
//场景下载失败了
|
|
isLoadFail = true;
|
|
}
|
|
//场景加载完毕
|
|
_loadingState = LoadingState.ScenePreLoaded;
|
|
|
|
CoroutinePool.AddTask(
|
|
LoadWorldAsync(
|
|
_loadingArgs.MapSetting.MapId,
|
|
_loadingArgs.MapSetting.Name,
|
|
_loadingArgs.MapSetting.LevelName,
|
|
_loadingArgs.MapSetting.CameraName,
|
|
_loadingArgs.MapSetting.CameraNameNight,
|
|
_loadingArgs.LineID,_loadingArgs.Position,
|
|
isLoadFail));
|
|
|
|
});
|
|
},
|
|
() =>
|
|
{
|
|
GameCenter.GameSceneSystem.ReturnToLogin();
|
|
});
|
|
}
|
|
|
|
private void BackToDefaultMap(bool tologin)
|
|
{
|
|
int backMapId = 102599;
|
|
if (tologin)
|
|
{
|
|
//返回的是同一张地图 直接返回登录
|
|
GameCenter.GameStateSystem.ChangeState((int)GameStateId.RetToLogin, 1);
|
|
}
|
|
else
|
|
{
|
|
NetHandler.SendMessage_TransportWorldMap(backMapId, 0);
|
|
}
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region 场景读取
|
|
|
|
IEnumerator LoadBaseScene(String name, String levelName)
|
|
{
|
|
//加载一个中间场景// 清除上一个场景数据
|
|
FLogger.LogTime("LoadOffScene!");
|
|
SceneManager.LoadScene(AssetConstDefine.SceneOffName);
|
|
|
|
|
|
//GameCenter.LuaSystem.Adaptor.SetLoadingFormProgress(0.5f);
|
|
|
|
FLogger.LogTime("LoadLevel! : " + levelName);
|
|
|
|
yield return new WaitForEndOfFrame();
|
|
// 加载目标场景
|
|
SceneManager.LoadScene(levelName);
|
|
|
|
|
|
yield return new WaitForEndOfFrame();
|
|
|
|
SceneRootAssetsLoader.ReleaseSceneBundle();
|
|
}
|
|
|
|
// 加载场景
|
|
IEnumerator LoadWorldAsync(int id, string name, string levelName, string dayCameraName, string nightCameraName, int lineID, Vector2? position = null, bool isFail = false)
|
|
{
|
|
try
|
|
{
|
|
GameCenter.LuaSystem.Adaptor.SetLoadingFormProgress(0.9f);
|
|
FLogger.LogTime("Start LoadWorldAsync!");
|
|
_loadingState = LoadingState.Loading;
|
|
yield return new WaitForEndOfFrame();
|
|
|
|
//1.开始加载进行物理场景的切换
|
|
if (isFail)
|
|
{
|
|
//直接加载一个空场景
|
|
FLogger.LogTime("LoadEmptyScene!");
|
|
|
|
SceneManager.LoadScene(AssetConstDefine.SceneEmptyName);
|
|
yield return new WaitForEndOfFrame();
|
|
FLogger.LogTime("空场景加载完成!");
|
|
}
|
|
else
|
|
{
|
|
//1.1加载一个中间场景// 清除上一个场景数据
|
|
FLogger.LogTime("LoadOffScene!");
|
|
|
|
SceneManager.LoadScene(AssetConstDefine.SceneOffName);
|
|
//yield return SceneManager.LoadSceneAsync(AssetConstDefine.SceneOffName, LoadSceneMode.Single);
|
|
|
|
yield return new WaitForEndOfFrame();
|
|
|
|
//1.2加载目标场景
|
|
float testTime = Time.realtimeSinceStartup;
|
|
FLogger.LogTime("LoadLevel! : " + levelName);
|
|
var option = SceneManager.LoadSceneAsync(levelName, LoadSceneMode.Single);
|
|
if (option == null)
|
|
{
|
|
//加载空场景
|
|
SceneManager.LoadScene(AssetConstDefine.SceneEmptyName);
|
|
yield return new WaitForEndOfFrame();
|
|
FLogger.LogTime("空场景加载完成!");
|
|
}
|
|
else
|
|
{
|
|
while (!option.isDone && option.progress < 1)
|
|
{
|
|
yield return new WaitForEndOfFrame();
|
|
}
|
|
FLogger.LogTime("场景异步加载完成! : " + levelName);
|
|
}
|
|
//SceneManager.LoadScene(levelName);
|
|
}
|
|
|
|
//1.3删除场景的bundle
|
|
SceneRootAssetsLoader.ReleaseSceneBundle();
|
|
|
|
|
|
yield return new WaitForEndOfFrame();
|
|
|
|
//2.物理场景切换成功后,开始创建逻辑场景
|
|
FLogger.LogTime("Create Logic Scene");
|
|
//Debug.LogError(string.Format("加载场景花费的时间{0}", Time.realtimeSinceStartup - testTime));
|
|
|
|
_targetScene = new GameScene();
|
|
//加载场景的一些逻辑数据信息--寻路等.
|
|
FLogger.LogTime("LoadSingleMapInfo!");
|
|
GameCenter.PathFinderSystem.LoadSingleMapInfo(DeclareMapsetting.Get(id));
|
|
FLogger.LogTime("LoadSingleMapInfo Finish!");
|
|
_targetScene.Load(id, name, levelName, dayCameraName, nightCameraName, false, false);
|
|
_targetScene.LineID = lineID;
|
|
_targetScene.FrontMapID = _loadingArgs.FrontMapID;
|
|
FLogger.LogTime("LogicScene Is Created!");
|
|
//加载玩家周围区域物件资源
|
|
FLogger.LogTime("Init SceneRestoreSystem !");
|
|
if(_targetScene.GetUnitySceneRoot() != null)
|
|
GameCenter.SceneRestoreSystem.InitSceneData(_targetScene.GetUnitySceneRoot().gameObject, position);
|
|
FLogger.LogTime("SceneRestoreSystem Init Finish !");
|
|
yield return new WaitForEndOfFrame();
|
|
|
|
//3.加载玩家自己的数据
|
|
//这里需要判断,如果角色玩家数据为空,表示是第一次登陆游戏
|
|
//否则,需要重新加载玩家数据,
|
|
if (LocalPlayerRoot.LocalPlayer != null)
|
|
{
|
|
_targetScene.ReloadLocalPlayer(_loadingArgs.Position);
|
|
}
|
|
yield return new WaitForEndOfFrame();
|
|
FLogger.LogTime("ChangeToState GameStateId.World");
|
|
|
|
if (_targetScene != null)
|
|
{
|
|
_targetScene.TransType = _loadingArgs.transType;
|
|
_targetScene.TransParam = _loadingArgs.transParam;
|
|
}
|
|
//OwnerGameCase.ChangeToState(GameStateId.World, _targetScene); // 直接进入world state
|
|
GameCenter.GameStateSystem.ChangeState((int)GameStateId.World, _targetScene);
|
|
}
|
|
finally
|
|
{
|
|
_targetScene = null;
|
|
//恢复网络数据处理, 恢复心跳
|
|
//发送一个进入地图成功的消息给服务端
|
|
FLogger.LogTime("Client EnteredMap! finally");
|
|
}
|
|
|
|
yield return new WaitForEndOfFrame();
|
|
FLogger.LogTime("Client EnteredMap!");
|
|
|
|
_loadingState = LoadingState.EndLoading;
|
|
}
|
|
|
|
// 删除已加载数据 -- 断线等状态强制转换
|
|
private void ReleaseData()
|
|
{
|
|
try
|
|
{
|
|
if (_targetScene != null)
|
|
{
|
|
_targetScene.Unload();
|
|
_targetScene = null;
|
|
}
|
|
GameCenter.GameSceneSystem.SceneSweepPrefab();
|
|
GameCenter.GameSceneSystem.SceneSweepAsset();
|
|
}
|
|
catch (System.Exception ex)
|
|
{
|
|
FLogger.LogException(ex);
|
|
}
|
|
}
|
|
|
|
#endregion
|
|
|
|
}
|
|
|
|
}
|