#region Copyright RenGuiYou. All rights reserved. //===================================================== // NeatlyFrameWork // Author: RenGuiyou // Feedback: mailto:750539605@qq.com //===================================================== #endregion using System; using Neatly.Load; using Neatly.Load.Manager; using UnityEngine; using Object = UnityEngine.Object; namespace Neatly.Module { public class LoadModule : ModuleSingleton { #region property public const string MANIFEST_NAME = NeatlyConfig.NAME_MANIFEST; private bool m_UseBundle; AssetBundleManifest m_Manifest; #endregion #region Pool //loader bundle pool private readonly LoaderPool m_LoaderPool = new LoaderPool(); #endregion #region subitem manager private readonly AssetBundleMapManager m_AssetBundleMapManager = Singleton.Instance; private readonly AtlasLoadManager m_AtlasLoadManager = Singleton.Instance; private readonly LuaLoadManager m_LuaLoadManager = Singleton.Instance; private readonly SoundLoadManager m_SoundLoadManager = Singleton.Instance; private readonly VideoLoadManager m_VideoLoadManager = Singleton.Instance; private readonly SceneLoadManager m_SceneLoadManager = Singleton.Instance; #endregion public override void Init() { SetUseBundle(NeatlyConfig.AssetBundleEnable); #if UNITY_EDITOR if (m_UseBundle) #endif { LoadManifest(); NeatlyFrame.Instance.RegistDestroyAction(m_LoaderPool.LoseRef); } //以下为初始化各个子管理器 m_AssetBundleMapManager.Init(this); m_AtlasLoadManager.Init(this); m_SceneLoadManager.Init(this); m_VideoLoadManager.Init(this); } //热加载 public override void HotReload() { #if UNITY_EDITOR if (m_UseBundle) #endif { //重载manifest HotLoadManifest(); } m_SoundLoadManager.Init(this); m_VideoLoadManager.Init(this); m_LuaLoadManager.Init(this); m_SceneLoadManager.Init(this); //重载AssetBundle映射表 m_AssetBundleMapManager.HotReload(); } public void SetUseBundle(bool useBundle) { m_UseBundle = useBundle; } public bool GetUseBundle() { return m_UseBundle; } public void ClearVersion() { m_LoaderPool.ClearVersion(); } public string[] GetAllDependencies(string bundleName) { return m_Manifest.GetAllDependencies(bundleName); } public T LoadAsset(string path, Action callback = null, bool sync = true, bool persistent = false) where T : Object { T source = null; LoadAssetLoader(path, typeof(T), data => { if (data == null) { NDebug.LogError("材质加载失败: path:{0}", path); return; } source = data as T; callback?.Invoke(source); }, sync, persistent); return source; } public T LoadAssetNoAddRef(string path, Action callback = null, bool sync = true, bool persistent = false) where T : Object { T source = null; LoadAssetLoader(path, typeof(T), data => { if (data == null) { NDebug.LogError("材质加载失败: path:{0}", path); return; } source = data as T; callback?.Invoke(source); }, sync, persistent, true); return source; } //加载图集 public NAtlas LoadAtlasInfo(string atlasName) { Loader loader = null; loader = m_LoaderPool.GetAtlasLoader(atlasName); if (loader == null) { string path = string.Format("{0}{1}", NeatlyConfig.PATH_ATLAS_TP, atlasName); loader = LoadAssetLoader(path, typeof(GameObject), null); } loader.AddRefenceCount(); return loader.AtlasInfo; } public void AddAtlasRef(string atlasName) { m_LoaderPool.AddAtlasRef(atlasName); } //解除Atlas引用 public void LoseAtlasRef(string atlasName) { m_LoaderPool.LoseAtlasRef(atlasName); } public Loader LoadAssetLoader(string path, Type type, Action callback, bool sync = true, bool persistent = false, bool notAddRef = false) { #if UNITY_EDITOR if (m_UseBundle) #endif { return LoadAssetFromBundle(path, type, callback, sync, persistent, notAddRef); } #if UNITY_EDITOR path = string.Format("{0}{1}", path, GetSuffix(type)); return LoadAssetFile(path, callback, sync); #endif } #region LoadAssetBundle //加载Manifest private void LoadManifest() { if (m_Manifest != null) return; var result = Loader.AutoLoad(MANIFEST_NAME).ResultObject; AssetBundle resultObject = result as AssetBundle; if (resultObject == null) { Debug.LogErrorFormat("[Manifest错误] Path:{0}", MANIFEST_NAME); return; } m_Manifest = resultObject.LoadAsset("AssetBundleManifest"); resultObject.Unload(false); } //加载Manifest private void HotLoadManifest() { var result = Loader.AutoLoad(MANIFEST_NAME).ResultObject; AssetBundle resultObject = result as AssetBundle; if (resultObject == null) { Debug.LogErrorFormat("[Manifest错误] Path:{0}", MANIFEST_NAME); return; } m_Manifest = resultObject.LoadAsset("AssetBundleManifest"); resultObject.Unload(false); } //加载AssetBundle public Loader LoadAssetBundle(string path, Action callback, bool sync = true, bool persistent = false, bool isDependency = false) { #if UNITY_EDITOR if (path.IndexOf("data_ttf") != -1) { return null; } #endif path = AssetBundleMapManager.Instance.Get(path); //缓存有就拿缓存 Loader result = m_LoaderPool.Get(path, isDependency); if (result != null) { if (callback != null) callback(result); return result; } LoadDependencies(path, sync, persistent); //同步 if (sync) { var loader = Loader.AutoLoad(path); loader.SetPersistent(persistent); if (isDependency) { loader.AddDependCount(); } m_LoaderPool.Add(loader.Path, loader); if (callback != null) callback(loader); return loader; } //异步 Loader.AutoLoad(path, loader => { loader.SetPersistent(persistent); if (isDependency) { loader.AddDependCount(); } m_LoaderPool.Add(loader.Path, loader); if (callback != null) callback(loader); }, false); return null; } //加载依赖 private void LoadDependencies(string name, bool sync, bool persistent) { string[] dependDirs = m_Manifest.GetAllDependencies(name); for (int i = 0; i < dependDirs.Length; i++) { LoadAssetBundle(dependDirs[i], null, sync, persistent, true); } } public Loader LoadAssetFromBundle(string path, Type type, Action callback, bool sync = true, bool persistent = false, bool notAddRef = false) { if (callback == null) { return LoadAssetBundle(path, null, sync, persistent); } return LoadAssetBundle(path, loader => { string name = path.GetFileName(); var asset = loader.LoadAsset(name, type); if (notAddRef) { loader.LoseRefenceCount(); } if (asset == null) { Debug.LogErrorFormat("Bundle加载资源错误, path:{0},name:{1}, asset is null", path, name); } callback(asset); }, sync, persistent); } #endregion //直接加载assetbundle public Loader LoadAssetBundleDirect(string path) { return Loader.AutoLoad(path); } //获取指定loader public Loader GetLoader(string path) { Loader loader = m_LoaderPool.Get(path, false); return loader; } #region LoadAssetFile private Loader LoadAssetFile(string path, Action callback, bool sync = true) { if (!sync && callback == null) { NDebug.LogError("[LoadModule] path:{0} 加载模式为异步,却无回调.", path); } if (callback == null) { var loader = Loader.AutoLoad(path); m_LoaderPool.Add(loader.Path, loader); return loader; } Loader.AutoLoad(path, loader => { callback(loader.ResultObject); m_LoaderPool.Add(loader.Path, loader); }, sync); return null; } public T LoadAssetFileSync(string path) where T : Object { return Loader.AutoLoad(path).ResultObject as T; } #endregion public override void Update(float dt) { m_LoaderPool.Update(); } #region 可视化工具接口(业务与框架皆不可使用) public System.Collections.Generic.Dictionary GetAllLoader() { return m_LoaderPool.GetAllLoader(); } #endregion #if UNITY_EDITOR private static string GetSuffix(Type type) { if (type == typeof(GameObject)) return ".prefab"; if (type == typeof(AtlasConfig)) return ".asset"; if (type == typeof(Material)) return ".mat"; return string.Empty; } #endif } }