// *********************************************************************** // Assembly : Unity // Author : Kimch // Created : 2018-2-29 // Description : 游戏当前场景,负责游戏的场景数据保存和提供常用方法 // Last Modified By : // Last Modified On : // *********************************************************************** // // // *********************************************************************** #define USE_AddressableAssets using System; using System.Collections; using System.Collections.Generic; using UnityEngine; using UnityEngine.AddressableAssets; using UnityEngine.ResourceManagement.AsyncOperations; using Object = UnityEngine.Object; namespace G { partial class GameScene : MonoBehaviour, F.IAsyncResult { #region Field public event Action enterSceneCallback; public readonly Dictionary sceneCommonAssets = new Dictionary(); private object _sceneUserData; #endregion #region Property /// /// 当前场景的服务器ID(考虑到副本场景可能资源ID和场景服务器ID不一致的情况) /// public int sceneId { get; set; } /// /// 配置表Id /// public int itemId { get; set; } /// /// /// public bool isLoading { get; private set; } #endregion #region Method /// /// 暂时只用一个场景 /// /// public void EnterScene(int id, object userData = null) { _sceneUserData = userData; if (id == 0) { if (this.sceneId != 0) { this.sceneId = 0; this.itemId = 0; //GameLevel.Instance.OnExitScene(); //EntityManager.Instance.OnExitScene(); //Platform.Instance.ReportEvent("exit_scene", ""); } StartCoroutine(LoadScene(id)); } else if (this.sceneId != id) { this.sceneId = 1; this.itemId = id; StartCoroutine(LoadScene(id)); //Platform.Instance.ReportEvent("enter_scene", ""); } else { this.sceneId = 2; this.OnEnterSceneCompleted(0); } } private void OnEnterSceneCompleted(int code) { if (this.sceneId != 0) { //初始化数据 //InitSceneCamera(); //KUIWindow.CloseWindow(); //KUIWindow.OpenWindow(); } else { this.isLoading = false; if ("again_level".Equals(_sceneUserData)) { if (LevelProxy.Instance.AgainStartLevel() != 0) { KUIWindow.OpenWindow(_sceneUserData); } } else if ("endless".Equals(_sceneUserData)) { KUIWindow.OpenWindow(_sceneUserData); KUIWindow.OpenWindow(_sceneUserData); } else if ("sword".Equals(_sceneUserData)) { KUIWindow.OpenWindow(_sceneUserData); KUIWindow.OpenWindow(_sceneUserData); } else if ("copy".Equals(_sceneUserData)) { KUIWindow.OpenWindow(_sceneUserData); KUIWindow.OpenWindow(_sceneUserData); } else { //打开主界面 KUIWindow.OpenWindow(_sceneUserData); } } enterSceneCallback?.Invoke(); } /// /// /// /// private IEnumerator LoadCommon(int id) { if (id > 0 && sceneCommonAssets.Count == 0) { _progress = 0f; AssetProxy.Instance.CreateReleasePool("scene_common"); var handle = AssetProxy.Instance.TryGetAssetsAsync("w_common", "scene_common"); yield return handle; if (handle.Status == AsyncOperationStatus.Succeeded) { var objs = handle.Result; foreach (GameObject obj in objs) { #if UNITY_EDITOR Debug.Log(obj.name); #endif sceneCommonAssets[obj.name] = obj; } } _progress = 0.2f; } } private void UnloadCommon() { sceneCommonAssets.Clear(); AssetProxy.Instance.RemoveReleasePool("scene_common"); } /// /// /// /// private IEnumerator LoadScene(int id) { if (id > 0) { KUIWindow.OpenWindow(this); yield return LoadCommon(id); LoadSceneAsync("stage", this.OnEnterSceneCompleted); } else { LoadSceneAsync("main", this.OnEnterSceneCompleted); } } public void EnterCopyScene(int id) { if (this.sceneId != id) { this.sceneId = 1; this.itemId = id; StartCoroutine(LoadCopyScene(id)); } } private IEnumerator LoadCopyScene(int id) { if (id == 8888) { KUIWindow.OpenWindow(this); yield return null; LoadSceneAsync("stage_ride", this.OnEnterSceneCompleted); } } #endregion #region Async /// /// /// private string _currentSceneName; private bool _loading; private float _progress; #if USE_AddressableAssets AsyncOperationHandle _sceneAOHandle; #endif /// /// /// /// /// public void LoadSceneAsync(string name, Action completed) { StartCoroutine(LoadSceneCoroutine(name, completed)); } /// /// /// public void UnloadScene() { StartCoroutine(LoadSceneCoroutine(null, null)); } /// /// /// /// /// /// private IEnumerator LoadSceneCoroutine(string sceneName, Action completed) { if (_currentSceneName == sceneName) { completed?.Invoke(0); yield break; } _loading = true; _progress = 0f; if (!string.IsNullOrEmpty(_currentSceneName)) { //#if USE_AddressableAssets // var unloadHandle = Addressables.UnloadSceneAsync(_sceneAOHandle); // while (!unloadHandle.IsDone) // { // _progress = unloadHandle.PercentComplete * 0.2f + 0.2f; // yield return null; // } //#else // var asyncOp = SceneManager.UnloadSceneAsync(_currentSceneName); // if (asyncOp != null) // { // while (!asyncOp.isDone) // { // _progress = asyncOp.progress * 0.2f; // yield return null; // } // } //#endif var asyncOp = Resources.UnloadUnusedAssets(); if (asyncOp != null) { while (!asyncOp.isDone) { _progress = asyncOp.progress * 0.2f; yield return null; } } _currentSceneName = null; } if (!string.IsNullOrEmpty(sceneName)) { #if USE_AddressableAssets var asyncOp = Addressables.LoadSceneAsync(sceneName); while (!asyncOp.IsDone) { _progress = asyncOp.PercentComplete * 0.8f + 0.2f; yield return null; } _sceneAOHandle = asyncOp; #else var asyncOp = SceneManager.LoadSceneAsync(name); while (!asyncOp.isDone) { _progress = asyncOp.progress * 0.8f + 0.2f; yield return null; } #endif _progress = 1f + float.Epsilon; _currentSceneName = sceneName; } _loading = false; completed?.Invoke(0); } bool F.IAsyncResult.isDone { get { return _progress > 1f; } } string F.IAsyncResult.errorMsg { get { return ""; } } float F.IAsyncResult.progress { get { return _progress; } } object F.IAsyncResult.userData { get { return this; } } #endregion #region Unity public static GameScene Instance; private void Awake() { Instance = this; } #endregion } }