218 lines
4.1 KiB
C#
Raw Permalink Normal View History

2025-05-18 01:04:31 +08:00
// ***********************************************************************
// Assembly : Unity
// Author : Kimch
// Created : 2018-04-27
//
// Last Modified By : Kimch
// Last Modified On :
// ***********************************************************************
// <copyright file= "SceneLoader" company="Kunpo"></copyright>
// <summary></summary>
// ***********************************************************************
#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
/// <summary>
///
/// </summary>
public class SceneLoader : MonoBehaviour, F.IAsyncResult
{
#region Field
/// <summary>
///
/// </summary>
private string _currentSceneName;
private bool _loading;
private float _progress;
#if USE_AddressableAssets
AsyncOperationHandle _sceneAOHandle;
#endif
#endregion
/// <summary>
///
/// </summary>
public bool isLoading
{
get { return _loading; }
}
/// <summary>
///
/// </summary>
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<SceneLoader>();
}
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
/// <summary>
///
/// </summary>
/// <param name="name"></param>
/// <param name="action"></param>
public void LoadSceneAsync(string name, Action<int> completed)
{
if (_currentSceneName != name)
{
_loading = true;
_progress = 0f;
StartCoroutine(LoadSceneCoroutine(name, completed));
}
else
{
completed?.Invoke(0);
}
}
/// <summary>
///
/// </summary>
public void UnloadScene()
{
if (_currentSceneName != null)
{
_loading = true;
_progress = 0f;
StartCoroutine(LoadSceneCoroutine(null, null));
}
}
/// <summary>
///
/// </summary>
/// <param name="name"></param>
/// <param name="completed"></param>
/// <returns></returns>
private IEnumerator LoadSceneCoroutine(string name, Action<int> 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
}
}