123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442 |
- using System;
- using System.Collections;
- using System.Collections.Generic;
- using UnityEngine;
- using UnityEngine.SceneManagement;
- namespace TFramework
- {
- public class ResourceManager : BaseManager
- {
- /// <summary>
- /// 所有AssetBundle资源包清单
- /// </summary>
- public AssetBundleManifest AssetBundleManifest { get; private set; }
- /// <summary>
- /// 缓存的所有AssetBundle包【AB包名称、AB包】
- /// </summary>
- public Dictionary<string, AssetBundle> AssetBundles { get; private set; } = new Dictionary<string, AssetBundle>();
- /// <summary>
- /// 当前激活的场景
- /// </summary>
- public Scene CurrentScene { get; private set; }
- public void Awake()
- {
- CurrentScene= SceneManager.GetActiveScene();
- }
- public T LoadAsset<T>(LoadResHandle<T> resHandle) where T : UnityEngine.Object
- {
- return LoadAsset<T>(resHandle.ResourcePath, resHandle.AssetPath, resHandle.AssetBundleName, resHandle.LoadMode);
- }
- /// <summary>
- /// 同步加载资源
- /// </summary>
- /// <typeparam name="T"></typeparam>
- /// <param name="resPath"></param>
- /// <param name="assetPath"></param>
- /// <param name="assetBundleName"></param>
- /// <param name="resLoadMode"></param>
- /// <returns></returns>
- public T LoadAsset<T>(string resPath, string assetPath, string assetBundleName = "", ResLoadMode resLoadMode = ResLoadMode.Resourece) where T : UnityEngine.Object
- {
- if (resLoadMode == ResLoadMode.Resourece)
- return Resources.Load<T>(resPath);
- else
- {
- #if UNITY_EDITOR
- if (AssetConfig.RuntimeMode == UpdateMode.Editor)
- return UnityEditor.AssetDatabase.LoadAssetAtPath<T>(assetPath);
- #endif
- if (AssetBundleManifest == null)
- {
- if (!AssetBundles.ContainsKey(AssetConfig.AssetBundleManifestName))
- AssetBundles.Add(AssetConfig.AssetBundleManifestName,
- AssetBundle.LoadFromFile(AssetConfig.AssetBundleRootPath + AssetConfig.AssetBundleManifestName));
- AssetBundleManifest = AssetBundles[AssetConfig.AssetBundleManifestName].LoadAsset<AssetBundleManifest>("AssetBundleManifest");
- }
- string[] dependencies = AssetBundleManifest.GetAllDependencies(assetBundleName);
- for (int i = 0; i < dependencies.Length; i++)
- {
- if (!AssetBundles.ContainsKey(dependencies[i]))
- AssetBundles.Add(dependencies[i], AssetBundle.LoadFromFile(AssetConfig.AssetBundleRootPath + dependencies[i]));
- }
- if (!AssetBundles.ContainsKey(assetBundleName))
- AssetBundles.Add(assetBundleName, AssetBundle.LoadFromFile(AssetConfig.AssetBundleRootPath + assetBundleName));
- return AssetBundles[assetBundleName].LoadAsset<T>(assetPath);
- }
- }
- /// <summary>
- /// 同步加载Resources下的资源
- /// </summary>
- /// <typeparam name="T">资源类型</typeparam>
- /// <param name="resPath">资源路径</param>
- /// <returns></returns>
- public T LoadAsset<T>(string resPath) where T : UnityEngine.Object => LoadAsset<T>(resPath, "", "");
- /// <summary>
- /// 同步加载AssetBundle资源
- /// </summary>
- /// <typeparam name="T">资源类型</typeparam>
- /// <param name="assetPath">资源路径</param>
- /// <param name="assetBundleName">AB包名</param>
- /// <returns></returns>
- public T LoadAsset<T>(string assetPath, string assetBundleName) where T : UnityEngine.Object => LoadAsset<T>("", assetPath, assetBundleName, ResLoadMode.AssetBundle);
- /// <summary>
- /// 异步加载资源
- /// </summary>
- /// <typeparam name="T">资源类型</typeparam>
- /// <param name="resPath">资源路径</param>
- /// <param name="onLoading">加载中事件</param>
- /// <param name="onLoadDone">加载完成事件</param>
- /// <returns></returns>
- public Coroutine LoadAssetAsync<T>(LoadResHandle<T> resHandle) where T : UnityEngine.Object
- {
- return StartCoroutine(LoadAsync(resHandle));
- }
- private IEnumerator LoadAsync<T>(LoadResHandle<T> resHandle) where T : UnityEngine.Object
- {
- UnityEngine.Object asset = null;
- if (resHandle.LoadMode == ResLoadMode.Resourece)
- {
- ResourceRequest request = Resources.LoadAsync<T>(resHandle.ResourcePath);
- while (!request.isDone)
- {
- resHandle.OnLoading?.Invoke(request.progress);
- yield return null;
- }
- resHandle.OnLoading?.Invoke(1);
- if (!request.asset)
- throw new UnityException($"资源加载失败:Resources文件夹中不存在资源 {resHandle.ResourcePath}!");
- else
- asset = request.asset;
- }
- else
- {
- #if UNITY_EDITOR
- if (AssetConfig.RuntimeMode == UpdateMode.Editor)
- {
- resHandle.OnLoading?.Invoke(1);
- asset = UnityEditor.AssetDatabase.LoadAssetAtPath<T>(resHandle.AssetPath);
- if (asset)
- asset = asset as T;
- else
- throw new UnityException($"加载资源失败:路径{resHandle.AssetPath}中不存在资源 {resHandle.AssetPath}!");
- }
- else
- {
- //等待相关依赖资源的加载
- yield return LoadDependenciesAssetBundleAsync(resHandle.AssetBundleName);
- yield return LoadAssetBundleAsync(resHandle.AssetBundleName, resHandle.OnLoading);
- if (AssetBundles.ContainsKey(resHandle.AssetBundleName.ToLower()))
- {
- //asset = AssetBundles[resHandle.AssetBundleName].LoadAsset<T>(resHandle.AssetPath);
- AssetBundleRequest request = AssetBundles[resHandle.AssetBundleName.ToLower()].LoadAssetAsync<T>(resHandle.AssetPath);
- yield return request;
- while (!request.isDone)
- {
- resHandle.OnLoading(request.progress / 2 + 0.5f);
- yield return null;
- }
- asset = request.asset;
- if (!asset)
- throw new UnityException(string.Format("加载资源失败:AB包 {0} 中不存在资源 {1}!", resHandle.AssetBundleName, resHandle.AssetPath));
- }
- }
- #else
- yield return LoadDependenciesAssetBundleAsync(resHandle.AssetBundleName);
- yield return LoadAssetBundleAsync(resHandle.AssetBundleName, resHandle.OnLoading);
- if (AssetBundles.ContainsKey(resHandle.AssetBundleName.ToLower()))
- {
- AssetBundleRequest request = AssetBundles[resHandle.AssetBundleName.ToLower()].LoadAssetAsync<T>(resHandle.AssetPath);
- yield return request;
- while(!request.isDone)
- {
- resHandle.OnLoading(request.progress / 2+0.5f);
- yield return null;
- }
- asset = request.asset;
- if (!asset)
- throw new UnityException(string.Format("加载资源失败:AB包 {0} 中不存在资源 {1}!", resHandle.AssetBundleName, resHandle.AssetPath));
- }
- #endif
- }
- if (asset)
- {
- resHandle.OnLoadOver?.Invoke(asset as T);
- }
- else
- resHandle.OnLoadOver?.Invoke(null);
- }
- /// <summary>
- /// 异步加载场景(Resource模式)
- /// </summary>
- /// <param name="scenePath">场景路径</param>
- /// <param name="onLoading">加载中事件</param>
- /// <param name="onLoadDone">加载完成事件</param>
- /// <returns></returns>
- public Coroutine LoadSceneAsync(string scenePath, TAction<float> OnLoading, TAction<Scene> OnLoadOver, LoadSceneMode loadSceneMode = LoadSceneMode.Single)
- {
- return StartCoroutine(LoadScene(scenePath, ResLoadMode.Resourece, "", OnLoading, OnLoadOver, loadSceneMode));
- }
- /// <summary>
- /// 异步加载场景
- /// </summary>
- /// <param name="scenePath">场景路径</param>
- /// <param name="onLoading">加载中事件</param>
- /// <param name="onLoadDone">加载完成事件</param>
- /// <returns></returns>
- public Coroutine LoadSceneAsync(LoadResHandle<Scene> resHandle, LoadSceneMode loadSceneMode = LoadSceneMode.Single)
- {
- return StartCoroutine(LoadScene(resHandle.AssetPath,resHandle.LoadMode,resHandle.AssetBundleName,resHandle.OnLoading,resHandle.OnLoadOver, loadSceneMode));
- }
- private IEnumerator LoadScene(string scenePath, ResLoadMode loadMode ,string assetBundleName ,TAction<float> OnLoading,TAction<Scene> OnLoadOver, LoadSceneMode loadSceneMode)
- {
- if (SceneManager.GetSceneByPath(scenePath) == CurrentScene)
- {
- Debug.LogWarning($"场景{scenePath}已加载!");
- yield break;
- }
- if (loadMode == ResLoadMode.Resourece)
- {
- AsyncOperation ao = SceneManager.LoadSceneAsync(scenePath, loadSceneMode);
- while (!ao.isDone)
- {
- OnLoading?.Invoke(ao.progress);
- yield return null;
- }
- }
- else
- {
- yield return LoadDependenciesAssetBundleAsync(assetBundleName);
- #if UNITY_EDITOR
- if (AssetConfig.RuntimeMode == UpdateMode.Editor)
- {
- LoadSceneParameters parameters = new LoadSceneParameters()
- {
- loadSceneMode = LoadSceneMode.Single,
- localPhysicsMode = LocalPhysicsMode.None
- };
- AsyncOperation ao = UnityEditor.SceneManagement.EditorSceneManager.LoadSceneAsyncInPlayMode(scenePath, parameters);
- while (!ao.isDone)
- {
- OnLoading?.Invoke(ao.progress);
- yield return null;
- }
- }
- else
- {
- yield return LoadAssetBundleAsync(assetBundleName, OnLoading);
- AsyncOperation ao = SceneManager.LoadSceneAsync(scenePath, loadSceneMode);
- while (!ao.isDone)
- {
- OnLoading?.Invoke(ao.progress);
- yield return null;
- }
- }
- #else
- yield return LoadAssetBundleAsync(assetBundleName, OnLoading);
- AsyncOperation ao = SceneManager.LoadSceneAsync(scenePath, loadSceneMode);
- while (!ao.isDone)
- {
- OnLoading?.Invoke(ao.progress);
- yield return null;
- }
- #endif
- }
- OnLoading?.Invoke(1);
- OnLoadOver?.Invoke(SceneManager.GetSceneByPath(scenePath));
- CurrentScene = SceneManager.GetActiveScene();
- //SceneManager.SetActiveScene(CurrentScene);
- }
- /// <summary>
- /// 异步清理内存 回收垃圾
- /// </summary>
- /// <returns></returns>
- public Coroutine ClearMemoryAsync()
- {
- return StartCoroutine(ClearMemory());
- }
- /// <summary>
- /// 清理内存,释放空闲内存(异步)
- /// </summary>
- /// <returns>协程迭代器</returns>
- private IEnumerator ClearMemory()
- {
- yield return Resources.UnloadUnusedAssets();
- GC.Collect();
- GC.WaitForPendingFinalizers();
- }
- /// <summary>
- /// 异步卸载资源
- /// </summary>
- /// <returns></returns>
- public Coroutine UnLoadAsstAsync(ResLoadMode resLoadMode, string assetBundleName, bool unloadAllLoadedObjects = false)
- {
- return StartCoroutine(UnLoadAsst(resLoadMode, assetBundleName, unloadAllLoadedObjects));
- }
- private IEnumerator UnLoadAsst(ResLoadMode resLoadMode, string assetBundleName, bool unloadAllLoadedObjects = false)
- {
- yield return UnLoadAsset(ResLoadMode.Resourece, assetBundleName, unloadAllLoadedObjects);
- }
- /// <summary>
- /// 异步卸载场景
- /// </summary>
- /// <param name="scene"></param>
- /// <returns></returns>
- public Coroutine UnloadSceneAsync(Scene scene, TAction<float> OnUnloading = null, TAction OnUnloadOver = null)
- {
- return StartCoroutine(UnloadScene(scene, OnUnloading, OnUnloadOver));
- }
- private IEnumerator UnloadScene(Scene scene, TAction<float> OnUnloading, TAction OnUnloadOver)
- {
- AsyncOperation ao = SceneManager.UnloadSceneAsync(scene);
- while (!ao.isDone)
- {
- OnUnloading?.Invoke(ao.progress);
- yield return null;
- }
- OnUnloadOver?.Invoke();
- CurrentScene = SceneManager.GetActiveScene();
- }
- public IEnumerator UnLoadAsset(ResLoadMode resLoadMode, string assetBundleName, bool unloadAllLoadedObjects = false)
- {
- if (resLoadMode == ResLoadMode.Resourece)
- {
- yield return Resources.UnloadUnusedAssets();
- }
- else
- {
- if (AssetBundles.ContainsKey(assetBundleName))
- {
- AssetBundles[assetBundleName].Unload(unloadAllLoadedObjects);
- AssetBundles.Remove(assetBundleName);
- }
- yield return null;
- }
- }
- /// <summary>
- /// 异步加载AB包清单
- /// </summary>
- /// <returns>协程迭代器</returns>
- private IEnumerator LoadAssetBundleManifestAsync()
- {
- if (string.IsNullOrEmpty(AssetConfig.AssetBundleManifestName))
- {
- throw new UnityException("请设置资源配置文件的 AssetBundleManifestName 属性,为所有AB包提供依赖清单!");
- }
- else
- {
- if (AssetBundleManifest == null)
- {
- yield return LoadAssetBundleAsync(AssetConfig.AssetBundleManifestName, null);
- if (AssetBundles.ContainsKey(AssetConfig.AssetBundleManifestName))
- {
- AssetBundleManifest = AssetBundles[AssetConfig.AssetBundleManifestName].LoadAsset<AssetBundleManifest>("AssetBundleManifest");
- UnLoadAsset(ResLoadMode.AssetBundle, AssetConfig.AssetBundleManifestName);
- }
- }
- }
- yield return null;
- }
- /// <summary>
- /// 异步加载AB包(提供进度回调)
- /// </summary>
- /// <param name="assetBundleName">AB包名称</param>
- /// <param name="onLoading">加载中事件</param>
- /// <param name="isManifest">是否是加载清单</param>
- /// <returns>协程迭代器</returns>
- private IEnumerator LoadAssetBundleAsync(string assetBundleName, TAction<float> onLoading)
- {
- assetBundleName = assetBundleName.ToLower();
- if (!AssetBundles.ContainsKey(assetBundleName))
- {
- AssetBundleCreateRequest abRequst = AssetBundle.LoadFromFileAsync(AssetConfig.AssetBundleRootPath + assetBundleName);
- yield return abRequst;
- while (!abRequst.isDone)
- {
- onLoading?.Invoke(abRequst.progress / 2);
- yield return null;
- }
- if (abRequst.assetBundle)
- AssetBundles.Add(assetBundleName, abRequst.assetBundle);
- else
- throw new UnityException($" 未加载到AB包【{assetBundleName}】!");
- }
- onLoading?.Invoke(1);
- }
- /// <summary>
- /// 异步加载依赖AB包
- /// </summary>
- /// <param name="assetBundleName">AB包名称</param>
- /// <returns>协程迭代器</returns>
- private IEnumerator LoadDependenciesAssetBundleAsync(string assetBundleName)
- {
- #if UNITY_EDITOR
- if (AssetConfig.RuntimeMode != UpdateMode.Editor)
- {
- yield return LoadAssetBundleManifestAsync();
- if (AssetBundleManifest != null)
- {
- string[] dependencies = AssetBundleManifest.GetAllDependencies(assetBundleName);
- foreach (string item in dependencies)
- {
- if (AssetBundles.ContainsKey(item))
- continue;
- yield return LoadAssetBundleAsync(item, null);
- }
- }
- }
- #else
- yield return LoadAssetBundleManifestAsync();
- if (AssetBundleManifest != null)
- {
- string[] dependencies = AssetBundleManifest.GetAllDependencies(assetBundleName);
- foreach (string item in dependencies)
- {
- if (AssetBundles.ContainsKey(item))
- {
- continue;
- }
- yield return LoadAssetBundleAsync(item,null);
- }
- }
- #endif
- yield return null;
- }
- }
- }
|