// *********************************************************************** // Assembly : Unity // Author : Kimch // Created : 2018-04-27 // // Last Modified By : Kimch // Last Modified On : // *********************************************************************** // // // *********************************************************************** #define USE_AddressableAssets namespace G { using System; using System.Collections; using UnityEngine; using UnityEngine.SceneManagement; #if USE_AddressableAssets using UnityEngine.AddressableAssets; using UnityEngine.ResourceManagement.AsyncOperations; #endif /// /// /// public class SceneLoader : MonoBehaviour, F.IAsyncResult { #region Field /// /// /// private string _currentSceneName; private bool _loading; private float _progress; #if USE_AddressableAssets AsyncOperationHandle _sceneAOHandle; #endif #endregion /// /// /// public bool isLoading { get { return _loading; } } /// /// /// public bool showLoading { get; set; } #region Unity Method private static SceneLoader _Instance; public static SceneLoader Instance { get { if (_Instance is null) { _Instance = new GameObject(nameof(SceneLoader)).AddComponent(); } return _Instance; } } private void Awake() { _Instance = this; DontDestroyOnLoad(this.gameObject); SceneManager.sceneLoaded += this.OnSceneLoaded; SceneManager.sceneUnloaded += this.OnSceneUnloaded; } private void OnSceneLoaded(Scene arg0, LoadSceneMode arg1) { //Debug.Log($"OnSceneLoaded {arg0.name}"); } private void OnSceneUnloaded(Scene scene) { if (_currentSceneName == scene.name) { _currentSceneName = null; } } #endregion #region Method /// /// /// /// /// public void LoadSceneAsync(string name, Action completed) { if (_currentSceneName != name) { _loading = true; _progress = 0f; StartCoroutine(LoadSceneCoroutine(name, completed)); } else { completed?.Invoke(0); } } /// /// /// public void UnloadScene() { if (_currentSceneName != null) { _loading = true; _progress = 0f; StartCoroutine(LoadSceneCoroutine(null, null)); } } /// /// /// /// /// /// private IEnumerator LoadSceneCoroutine(string name, Action completed) { yield return null; if (!string.IsNullOrEmpty(_currentSceneName)) { #if USE_AddressableAssets var unloadHandle = Addressables.UnloadSceneAsync(_sceneAOHandle); while (!unloadHandle.IsDone) { _progress = unloadHandle.PercentComplete * 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 _currentSceneName = null; } if (!string.IsNullOrEmpty(name)) { #if USE_AddressableAssets var asyncOp = Addressables.LoadSceneAsync(name); 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 = name; } completed?.Invoke(0); _loading = false; } 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 } }