AssetBundle打包缓存加载机制

一、什么是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();
    }
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值