• AssetBundle


    AssetBundle

    设置资源AB

    基本上unity所包含的资源文件,除了脚本文件都可以设置成ab资源。
    enter description here

    生成AB资产

    生成AB有两种方式

    • 自定义打包
    • AssetBundles-Browser-master插件
    1. 预览AB

    这里使用插件打包,对于目前所有ab资源一目了然,如有ab设置错误也会有错误提示,我们已经设置好ab资源用它打开如图
    enter description here

    正是因为unity支持‘/’来分层,所以我们用文件层次来设置ab名称enter description here
    才使得对应ab包层级目录结构清晰明确
    2. 打包设置

    enter description here
    enter description here

    根据当前ab资源选择不同压缩模式比较

    压缩模式 UnCompression LZ4 LZMA
    Andriod平台大小 325kb 160kb 119kb
    • LZ4 解压读取速度快(推荐)
    • LZMA 压缩率高,文件占用空间小,解压比较慢

    获取AB加载

    大致流程图示

    下面示例从服务器中获取 tom ab资源一系列流程

    要测试在服务中的ab资源

    enter description here
    enter description here

    测试代码

    1.连接服务器,获取主依赖

    调用入口

    StartCoroutine(GetDepends(host, "AB_Andriod_LZ4"));

    具体实现

    /// <summary>
        /// 服务器地址
        /// </summary>
        string host = @"https://ab-test-1258795305.cos.ap-shanghai.myqcloud.com/";
    
        /// <summary>
        /// ab-依赖
        /// </summary>
        public Dictionary<string/*ab path*/, AB_DATA> dic_AB = new Dictionary<string, AB_DATA>();
    
        /// <summary>
        /// 获取主依赖,本地存储依赖关系,下载全部ab
        /// </summary>
        /// <param name="host_path">服务器根地址</param>
        /// <param name="dir_name">服务器下ab根文件名,以及主ab文件名称</param>
        /// <returns></returns>
        IEnumerator GetDepends(string host_path, string dir_name)
        {
            dic_AB.Clear();
    
            //目录跟路径
            string root_path = host_path + "/" + dir_name;
    
            //获取主ab,拿到manifest获取依赖关系
            AssetBundleManifest assetBundleManifestServer = null;  //服务器 总的依赖关系    
            UnityWebRequest ServerManifestWWW = UnityWebRequestAssetBundle.GetAssetBundle(root_path + "/" + dir_name);
            Debug.Log("HTTP : " + ServerManifestWWW.url.ToString());
            yield return ServerManifestWWW.SendWebRequest();
            assetBundleManifestServer = (AssetBundleManifest)DownloadHandlerAssetBundle.GetContent(ServerManifestWWW).LoadAsset("AssetBundleManifest");
    
    
            //存储各依赖关系
            string[] depends_name = assetBundleManifestServer.GetAllAssetBundles();
            for (int i = 0; i < depends_name.Length; i++)
            {
                AB_DATA ab_data = new AB_DATA();
                ab_data.name = depends_name[i];
                
                UnityWebRequest target_uwq = UnityWebRequestAssetBundle.GetAssetBundle(Path.Combine(root_path, ab_data.name));
                yield return target_uwq.SendWebRequest();
                if (target_uwq.isDone)
                {
                    //下载ab到本地
                    StartCoroutine(DownLoadAssetBundelAbdSave(Path.Combine(root_path, ab_data.name)));
                    //depends
                    var depends = assetBundleManifestServer.GetAllDependencies(ab_data.name);
                    ab_data.depends_name = new string[depends.Length];
                    for (int j = 0; j < depends.Length; j++)
                    {
                        ab_data.depends_name[j] = depends[j];
                    }
                    dic_AB.Add(depends_name[i], ab_data);
                }
    
            }
        }

    2.缓存已下载的ab资源

      /// <summary>
        /// 下载AB文件并保存到本地
        /// </summary>
        /// <returns></returns>
        IEnumerator DownLoadAssetBundelAbdSave(string url)
        {
            WWW www = new WWW(url);
            yield return www;
            if (www.isDone)
            {
                //表示资源下载完毕使用IO技术把www对象存储到本地
                SaveAssetBundle(Path.GetFileName(url), www.bytes, www.bytes.Length);
    
            }
        }
        /// <summary>
        /// 存储AB文件到本地
        /// </summary>
        private void SaveAssetBundle(string fileName, byte[] bytes, int count)
        {
            string dir_path = Application.persistentDataPath + "/" + fileName;
    
            Debug.Log("存储路径 : " + dir_path);
            Stream sw = null;
            FileInfo fileInfo = new FileInfo(dir_path);
            sw = fileInfo.Create();
            sw.Write(bytes, 0, count);
            sw.Flush();
            sw.Close();
            sw.Dispose();
            Debug.Log(fileName + "下载并存储完成");
        }

    3.从本地磁盘读取ab并实例化

    调用入口

     private void LoadStream_OnClick()
        {
            //设置要加载的目标物体名
            string ab_name = "tom.prefab";
            
            string dir_path = Application.persistentDataPath + "/" + ab_name;
            //从已缓存的字节文件中加载tom
            StartCoroutine(LoadABFormStream(dir_path));
    
            //加载tom所需的依赖
            string[] ad_names = dic_AB[ab_name].depends_name;
            for (int i = 0; i < ad_names.Length; i++)
            {
                string dir_path_depends = Path.Combine(Application.persistentDataPath, ad_names[i]);
    
               //加载依赖时,直接加载出其ab包即可,不需要分解其依赖类型再去实例,unity自会处理
                AssetBundle.LoadFromFile(dir_path_depends);
               //所以下面部分就不需要了
               // StartCoroutine(LoadABFormStream(dir_path_depends));
            }
    
        }

    相关方式实现

    /// <summary>
        /// 从字节文件读取ab,并且实例化
        /// </summary>
        /// <param name="dir_path"></param>
        /// <returns></returns>
        IEnumerator LoadABFormStream(string dir_path)
        {
            FileStream fileStream = new FileStream(dir_path, FileMode.Open, FileAccess.Read);
            AssetBundleCreateRequest request = AssetBundle.LoadFromStreamAsync(fileStream);
            yield return request;
    
            AssetBundle myLoadedAssetBundle = request.assetBundle;
            if (myLoadedAssetBundle == null)
            {
                Debug.Log("Failed to load AssetBundle!");
                yield break;
            }
            //实例化ab
            InstanceAB_FormAssetBundle(myLoadedAssetBundle, myLoadedAssetBundle.name);
            fileStream.Close();
        }
         private void InstanceAB_FormAssetBundle(AssetBundle assetBundle, string obj_name)
        {
    
            Object gameObject = null;
            if (obj_name.Contains(".mat"))
            {
                gameObject = assetBundle.LoadAsset<Material>(obj_name);
                Instantiate<Material>((Material)gameObject);
            }
            else if (obj_name.Contains(".prefab"))
            {
                gameObject = assetBundle.LoadAsset<GameObject>(obj_name);
                Instantiate<GameObject>((GameObject)gameObject);
            }
        }
  • 相关阅读:
    KVM虚拟化网卡管理
    KVM虚拟化存储管理
    OpenStack简介
    KVM虚拟机管理
    Jenkins持续集成
    Python函数
    Python文件处理
    Python语句
    Python数据类型的用法
    微信服务号开发小项目总结
  • 原文地址:https://www.cnblogs.com/Jean90/p/10940299.html
Copyright © 2020-2023  润新知