AssetBundle打包缓存加载机制

    科技2022-08-12  97

    一、什么是AssetBundle? 1.它存在于硬盘上的文件。可称之为压缩包。该压缩包里面有多个文件,这些文件可分为两类:serialized file和resources file(即序列化文件和源文件)。(1)serialized file:资源被打散放在一个对象中,最后统一被写进一个单独的文件(只有一个)(如:模型资源,prefab资源等)(2)resources file:某些二进制资源(如:图片、声音)被单独保存,方便快速加载。 2.它是一个AssetBundle对象,我们可以通过AssetBundle类从压缩包加载出来对象并使用,这个对象包含了所有当初添加到这个压缩包里面的内容。 下面是整理的缓存加载机制

    public class LoadAssetBundle : MonoBehaviour { public class CacehDependencies { public CacehDependencies(int _index, AssetBundle _assetBundle) { index = _index; assetBundle = _assetBundle; } public int index; public AssetBundle assetBundle; } List<CacehDependencies> cacehDependencies = new List<CacehDependencies>(); /// <summary> /// 若加载路径与打包路径不同,用这个 /// </summary> /// <param name="filePath"></param>加载路径 /// <param name="manifestBundleName"></param>须指定要加载的manifestAssetBundle /// <param name="abFileName"></param>要加载的ab /// <param name="prefabFileName"></param>预制体 无后缀 public GameObject loadAssetBundleFiles(string filePath, string manifestBundleName, string abFileName, string prefabFileName) { /** * 1.首先从打包路径获取依赖 * 这里加载的就是生成的同名文件ab */ AssetBundle manifestBundle = AssetBundle.LoadFromFile(getManifestFilePath(filePath, manifestBundleName)); /** * 2.获取依赖资源列表 */ if (manifestBundle != null) { try { AssetBundleManifest manifest = manifestBundle.LoadAsset<AssetBundleManifest>("AssetBundleManifest");//固定加载方式,通过 assetbundle Abs加载Abs.manifest manifestBundle.Unload(false); //获取加载ab的依赖信息,参数为ab名称,如cube.ab LoadDependencies(manifest, filePath, abFileName); } catch (InvalidCastException e) { Debug.LogException(e); } /** * 3.最后加载ab * 注意这里的LoadAsset的参数是Prefab的名称,无后缀,如cube而非cube.ab或cube.prefab */ AssetBundle ab = AssetBundle.LoadFromFile(generateAbsoluteFile(filePath, abFileName)); GameObject go = ab.LoadAsset(prefabFileName) as GameObject; ab.Unload(false); return go; } return null; } private void LoadDependencies(AssetBundleManifest manifest, string filePath, string abFileName) { string[] dependsFile = manifest.GetAllDependencies(abFileName); if (dependsFile.Length > 0) { //根据获取到的依赖信息加载所有依赖资源ab AssetBundle[] dependsBundle = new AssetBundle[dependsFile.Length]; for (int i = 0; i < dependsFile.Length; i++) { CacehDependencies cacehDependencies = GetContain(dependsFile[i]); if (cacehDependencies == null)//如果缓存没有依赖资源就再去加载 { string fp = generateAbsoluteFile(filePath, dependsFile[i]); Debug.Log(string.Format("depends:{0}:{1}", i, dependsFile[i])); dependsBundle[i] = AssetBundle.LoadFromFile(fp); CacehDependencies cacehDependencie = new CacehDependencies(1, dependsBundle[i]); } else //将依赖资源放入缓存中,加载一次资源缓存计数加一 { cacehDependencies.index += 1; } } } } private CacehDependencies GetContain(string name) { for (int i = 0; i < cacehDependencies.Count; i++) { if (cacehDependencies[i].assetBundle.name.Equals(name)) { return cacehDependencies[i]; } } return null; } //每十分钟遍历一次 public void GCCacehDependencies() { for (int i = 0; i < cacehDependencies.Count; i++) { if (cacehDependencies[i].index == 0)//如果计数等于0就卸载依赖资源 { cacehDependencies[i].assetBundle.Unload(false); } else { cacehDependencies[i].index -= 1;//如果计数大于0就计数减一 } } } /// <summary> /// 若打包路径和加载路径相同则使用这个 /// </summary> /// <param name="filePath"></param>打包路径和加载路径 /// <param name="abFileName"></param>加载ab文件名称 /// <param name="prefabFileName"></param>加载预制体 无后缀 public GameObject loadAssetBundleFiles(string filePath, string abFileName, string prefabFileName) { return loadAssetBundleFiles(filePath, "", abFileName, prefabFileName); } private string getManifestFilePath(string filePath, string manifestName) { if (string.IsNullOrEmpty(manifestName)) /*路径*/ { int lastSymbol = filePath.LastIndexOf('/'); string pathAssetBunldeName = filePath.Substring(lastSymbol); return (filePath + pathAssetBunldeName).Trim(); } else //name { return filePath + "/" + manifestName; } } private string generateAbsoluteFile(string filePath, string fileName) { return string.Concat(filePath, "/", fileName).Trim(); }
    Processed: 0.009, SQL: 8