//参数3:资源在跳转场景是否需要清空 public GameObject Instantiate(string path, bool setSceneObj = false, bool bClear = true) { uint crc = CrcHelper.StringToCRC32(path); //先尝试从缓存中取实例化Obj GameObjectItem gameObjectItem = GetGameObjectItemFromPool(crc); if (gameObjectItem == null) { gameObjectItem = m_gameObjectItemClassPool.Spawn(true); gameObjectItem.Crc = crc; gameObjectItem.Clear = bClear; ResourceMgr.Instance.LoadGameObjectItem(path, gameObjectItem); if (gameObjectItem.ResourceItem.Obj != null) { gameObjectItem.Obj = GameObject.Instantiate(gameObjectItem.ResourceItem.Obj) as GameObject; gameObjectItem.OfflineData = gameObjectItem.Obj.GetComponent <OfflineData>(); } } if (setSceneObj) { gameObjectItem.Obj.transform.SetParent(m_sceneGos, false); } gameObjectItem.Guid = gameObjectItem.Obj.GetInstanceID(); if (!m_gameObjectItemDict.ContainsKey(gameObjectItem.Guid)) { m_gameObjectItemDict.Add(gameObjectItem.Guid, gameObjectItem); } return(gameObjectItem.Obj); }
//加载指定ab包名的ab包 public AssetBundle LoadAssetBundle(string abName) { AssetBundleItem abItem = null; uint crc = CrcHelper.StringToCRC32(abName); //AB包名字创建crc if (!m_assetBundleItemDict.TryGetValue(crc, out abItem) || abItem == null) { AssetBundle assetBundle = null; string abFullPath = ABPathConfig.AssetBundleBuildTargetPath + "/" + abName; if (File.Exists(abFullPath)) { assetBundle = AssetBundle.LoadFromFile(abFullPath); } if (assetBundle == null) { Debug.Log("Load AssetBundle Error: " + abFullPath); return(null); } abItem = m_assetBundleItemPool.Spawn(true); abItem.assetBundle = assetBundle; abItem.refCount++; m_assetBundleItemDict.Add(crc, abItem); } else { abItem.refCount++; } return(abItem.assetBundle); }
//异步加载GameObject public void InstantiateAsync(string path, OnAsyncResourceObjFinished dealFinish, LoadAssetPriority priority, bool setSceneObject = false, object param1 = null, object param2 = null, object param3 = null, bool bClear = true) { if (string.IsNullOrEmpty(path)) { return; } uint crc = CrcHelper.StringToCRC32(path); GameObjectItem gameObjectItem = GetGameObjectItemFromPool(crc); if (gameObjectItem != null) { if (setSceneObject) { gameObjectItem.Obj.transform.SetParent(m_sceneGos, false); } if (dealFinish != null) { dealFinish(path, gameObjectItem.Obj, param1, param2, param3); } return; } gameObjectItem = m_gameObjectItemClassPool.Spawn(true); gameObjectItem.Crc = crc; gameObjectItem.SetSceneParent = setSceneObject; gameObjectItem.Clear = bClear; gameObjectItem.DealFinishCallback = dealFinish; gameObjectItem.Param1 = param1; gameObjectItem.Param2 = param2; gameObjectItem.Param3 = param3; //调用ResourceManager异步加载接口 ResourceMgr.Instance.AsyncLoadGameObjectItem(path, gameObjectItem, OnAsyncLoadGameObjectFinish, priority); }
//预加载资源 public void PreLoadAsset(string path) { if (string.IsNullOrEmpty(path)) { return; } uint crc = CrcHelper.StringToCRC32(path); ResourceItem item = GetAssetFromAssetCache(crc); if (item != null) { return; } Object obj = null; #if UNITY_EDITOR if (!m_loadFromAssetBundle) { item = AssetBundleManager.Instance.FindResourceItem(crc); if (item.Obj != null) { obj = item.Obj; } else { obj = LoadAssetByEditor <Object>(path); } } #endif if (obj == null) { item = AssetBundleManager.Instance.LoadResourceItem(crc); if (item != null && item.Ab != null) { if (item.Obj != null) { obj = item.Obj; } else { obj = item.Ab.LoadAsset <Object>(item.AssetName); } } } CacheAsset2AssetCache(path, ref item, crc, obj); //预加载的资源, 在场景跳转时,不清空缓存, 到底清除不清除,可以通过传递参数来控制, 而不是在代码中定死 item.Clear = false; //预加载,放入缓存 UnLoadAsset(obj, false); }
//同步加载资源,针对GameObject public GameObjectItem LoadGameObjectItem(string path, GameObjectItem gameObjectItem) { if (gameObjectItem == null) { return(null); } uint crc = gameObjectItem.Crc == 0 ? CrcHelper.StringToCRC32(path) : gameObjectItem.Crc; ResourceItem resouceItem = GetAssetFromAssetCache(crc); if (resouceItem != null) { gameObjectItem.ResourceItem = resouceItem; return(gameObjectItem); } Object obj = null; #if UNITY_EDITOR if (!m_loadFromAssetBundle) { resouceItem = AssetBundleManager.Instance.FindResourceItem(crc); if (resouceItem.Obj != null) { obj = resouceItem.Obj as Object; } else { obj = LoadAssetByEditor <Object>(path); } } #endif if (obj == null) { resouceItem = AssetBundleManager.Instance.LoadResourceItem(crc); if (resouceItem != null && resouceItem.Ab != null) { if (resouceItem.Obj != null) { obj = resouceItem.Obj as Object; } else { obj = resouceItem.Ab.LoadAsset <Object>(resouceItem.AssetName); } } } CacheAsset2AssetCache(path, ref resouceItem, crc, obj); resouceItem.Clear = gameObjectItem.Clear; gameObjectItem.ResourceItem = resouceItem; return(gameObjectItem); }
//同步资源加载,仅加载不需要实例化的资源(纹理图片,音频,视频,Prefab等) public T LoadAsset <T>(string path) where T : UnityEngine.Object { if (string.IsNullOrEmpty(path)) { return(null); } uint crc = CrcHelper.StringToCRC32(path); ResourceItem item = GetAssetFromAssetCache(crc); if (item != null) { return(item.Obj as T); } T obj = null; #if UNITY_EDITOR if (!m_loadFromAssetBundle) { item = AssetBundleManager.Instance.FindResourceItem(crc); if (item.Obj != null) { obj = item.Obj as T; } else { obj = LoadAssetByEditor <T>(path); } } #endif if (obj == null) { item = AssetBundleManager.Instance.LoadResourceItem(crc); if (item != null && item.Ab != null) { if (item.Obj != null) { obj = item.Obj as T; } else { obj = item.Ab.LoadAsset <T>(item.AssetName); } } } CacheAsset2AssetCache(path, ref item, crc, obj); return(obj); }
//卸载指定ab包名的ab包 public void UnLoadAssetBundle(string abName) { AssetBundleItem abItem = null; uint crc = CrcHelper.StringToCRC32(abName); if (m_assetBundleItemDict.TryGetValue(crc, out abItem) && abItem != null) { abItem.refCount--; if (abItem.refCount <= 0 && abItem.assetBundle != null) { abItem.assetBundle.Unload(true); abItem.Reset(); m_assetBundleItemPool.Recycle(abItem); m_assetBundleItemDict.Remove(crc); } } }
//根据路径卸载资源 public void UnloadAsset(string path, bool destroyObj = false) { if (string.IsNullOrEmpty(path)) { return; } uint crc = CrcHelper.StringToCRC32(path); ResourceItem item = null; if (!AssetCacheDict.TryGetValue(crc, out item) || item == null) { return; } if (item == null) { return; } item.RefCount--; DestroyResourceItem(item, destroyObj); }
//异步加载资源, 仅仅是不需要实例化的资源,音频,图片等 public void AsyncLoadAsset <T>(string path, OnAsyncResourceObjFinished dealFinished, LoadAssetPriority priority, object param1 = null, object param2 = null, object param3 = null, uint crc = 0) where T : UnityEngine.Object { if (crc == 0) { crc = CrcHelper.StringToCRC32(path); } ResourceItem item = GetAssetFromAssetCache(crc); if (item != null) { if (dealFinished != null) { dealFinished(path, item.Obj, param1, param2, param3); } return; } //判断是否在加载中 AsyncLoadAssetParam para = null; if (!m_loadingAssetDict.TryGetValue(crc, out para) || para == null) { para = m_asyncLoadAssetParamPool.Spawn(true); para.m_crc = crc; para.m_path = path; para.m_priority = priority; //这里应该还少了对Sprite的判定 m_loadingAssetDict.Add(crc, para); m_loadingAssetList[(int)priority].Add(para); } AsyncCallBack callback = m_asyncCallBackPool.Spawn(true); callback.m_resourceObjDealFinished = dealFinished; callback.m_param1 = param1; callback.m_param2 = param2; callback.m_param3 = param3; para.m_callbackList.Add(callback); }
//同步加载GameObject, 参数3:资源在跳转场景是否需要清空 public GameObject Instantiate(string path, bool bClear = true) { uint crc = CrcHelper.StringToCRC32(path); //先尝试从缓存中取实例化Obj GameObjectItem gameObjectItem = GetGameObjectItemFromPool(crc); if (gameObjectItem == null) { gameObjectItem = m_gameObjectItemClassPool.Spawn(true); gameObjectItem.Crc = crc; gameObjectItem.Clear = bClear; ResourceMgr.Instance.LoadGameObjectItem(path, gameObjectItem); if (gameObjectItem.ResourceItem.Obj != null) { gameObjectItem.Obj = GameObject.Instantiate(gameObjectItem.ResourceItem.Obj) as GameObject; } } gameObjectItem.Guid = gameObjectItem.Obj.GetInstanceID(); if (!m_gameObjectItemDict.ContainsKey(gameObjectItem.Guid)) { m_gameObjectItemDict.Add(gameObjectItem.Guid, gameObjectItem); } return(gameObjectItem.Obj); }
//根据文件路径名获取ResourceItem public ResourceItem LoadResourceItem(string filePath) { uint crc = CrcHelper.StringToCRC32(filePath); return(LoadResourceItem(crc)); }
//制作依赖关系 private static void MakeDependenceRelationShip() { string[] assetBundleNameAry = AssetDatabase.GetAllAssetBundleNames(); //得到所有的AssetBundle的名字 Dictionary <string, string> dict = new Dictionary <string, string>(); //记录需要被加载的资源 Dictionary <string, string> allDict = new Dictionary <string, string>(); //记录所有的资源 for (int i = 0; i < assetBundleNameAry.Length; i++) { string[] assetBundleAllFiles = AssetDatabase.GetAssetPathsFromAssetBundle(assetBundleNameAry[i]); //得到某个AssetBundle下的所有被标记的文件 for (int j = 0; j < assetBundleAllFiles.Length; j++) { if (assetBundleAllFiles[j].EndsWith(".cs") == false) { allDict.Add(assetBundleAllFiles[j], assetBundleNameAry[i]); } if (assetBundleAllFiles[j].EndsWith(".cs") == true || CanBeLoadByDynamic(assetBundleAllFiles[j]) == false) //生成依赖文件,我们只生成那些有可能会被实例化的资源,那些不可能被实例化的资源不需要写入依赖文件中 { continue; } dict.Add(assetBundleAllFiles[j], assetBundleNameAry[i]); //这个文件Assets/相对路径和对应这个文件所在的AB包名 } } //删除已经没有的AssetBundle包文件 DirectoryInfo directoryInfo = new DirectoryInfo(ABPathConfig.AssetBundleBuildTargetPath); FileInfo[] fileInfoAry = directoryInfo.GetFiles("*", SearchOption.AllDirectories); foreach (FileInfo fileInfo in fileInfoAry) { bool isExists = false; foreach (string assetBundleName in assetBundleNameAry) { if (assetBundleName == fileInfo.Name) //AssetBundle包名和打包时标记名一致 { isExists = true; } } if (isExists == false && File.Exists(fileInfo.FullName)) { Debug.Log(fileInfo.Name + "这个包已经不需要存在了, 删除中..."); File.Delete(fileInfo.FullName); } } //写依赖文件 AssetBundleConfig config = new AssetBundleConfig(); config.ABList = new List <ABBase>(); foreach (string path in dict.Keys) { ABBase abBase = new ABBase(); abBase.Path = path; abBase.Crc = CrcHelper.StringToCRC32(path); abBase.ABName = dict[path]; abBase.AssetName = path.Remove(0, path.LastIndexOf("/") + 1); abBase.DependABList = new List <string>(); string[] resDependce = AssetDatabase.GetDependencies(path); for (int i = 0; i < resDependce.Length; i++) { string tempPath = resDependce[i]; if (tempPath == path || path.EndsWith(".cs")) //排除对本身文件和.cs脚本文件 { continue; } string abName = ""; if (allDict.TryGetValue(tempPath, out abName)) { if (abName == allDict[path]) { continue; } if (!abBase.DependABList.Contains(abName)) { abBase.DependABList.Add(abName); } } } config.ABList.Add(abBase); } //写入xml if (File.Exists(ABPathConfig.AssetBundleDependenceXmlPath)) { File.Delete(ABPathConfig.AssetBundleDependenceXmlPath); } FileStream fileStream = new FileStream(ABPathConfig.AssetBundleDependenceXmlPath, FileMode.Create, FileAccess.ReadWrite, FileShare.ReadWrite); StreamWriter sw = new StreamWriter(fileStream, System.Text.Encoding.UTF8); XmlSerializer xs = new XmlSerializer(config.GetType()); xs.Serialize(sw, config); sw.Close(); fileStream.Close(); //写入二进制 foreach (ABBase item in config.ABList) { item.Path = ""; } if (File.Exists(ABPathConfig.AssetBundleDependenceBytePath)) { File.Delete(ABPathConfig.AssetBundleDependenceBytePath); } fileStream = new FileStream(ABPathConfig.AssetBundleDependenceBytePath, FileMode.Create, FileAccess.ReadWrite, FileShare.ReadWrite); BinaryFormatter bf = new BinaryFormatter(); bf.Serialize(fileStream, config); fileStream.Close(); }