Unity之AssetBundle的实际应用

来源:互联网 发布:多益网络找回密码 编辑:程序博客网 时间:2024/06/11 14:35
AssetBundle是Unity一种特有的资源格式,其他的项目我不了解,从入行到现在经历的所有的Unity游戏项目,所需的资源都是打成Bundle的形式供项目使用。


AssetBundle的优点总结为以下几点:


1.资源压缩,可以减小安装包的大小。安装包大小其实对于一些中小cp来说是必须要控制的,或者说是越小越好,因为游戏上线大推之前,某些xx渠道会给你设很多障碍,比如要接GooglePlay,包体必须要控制到150m;安装包越大,推行费用越高等等,这里就不细说了。
2.支持各种资源打包,AssetBundles可以包含Unity可以识别的任何类型的资源,包括场景,模型,材质,纹理,音效以及自定义的二进制数据。唯一的例外是,脚本资源是不被允许的,但是有一种特殊情况,当prefab上挂了某一脚本被打成Bundle,在你的正在使用的项目中有同名脚本,该脚本会被运行,如果没有,该脚本组件失效。
3.支持异步加载,可以很好地缓解资源加载卡顿问题
4.支持热更新,AsseBundle文件放到远程服务器,在客户端下载覆盖更新。


以下主要介绍以下AssetBundle的用法。

话不多说。


一.打包  

项目里打包主角模型 ,其他文件类型例如武器,特效,贴图等打包方式基本一致,只是在判断原始资源类型处不同

Caching.CleanCache();//清缓存        // 保证目标文件夹存在且为空        string targetPath = Application.dataPath + "/StreamingAssets/Role/Player/";        if (System.IO.Directory.Exists(targetPath))        {            System.IO.Directory.Delete(targetPath, true);        }        System.IO.Directory.CreateDirectory(targetPath); string playerPath = Application.dataPath + "/BuildRes/Roles/Player/Player/";        string[] playerDir = System.IO.Directory.GetFileSystemEntries(playerPath);        foreach (string p in playerDir)        {            if (p.EndsWith(".prefab"))            {                int nPos = p.IndexOf("Assets/BuildRes/Roles/Player/Player");                string assetPath = p.Substring(nPos);                nPos = assetPath.LastIndexOf("/");                string fileName = assetPath.Substring(nPos + 1, assetPath.Length - nPos - 1 - ".prefab".Length);                Object asset = AssetDatabase.LoadMainAssetAtPath(assetPath);                uint crc = 0;                if (null != asset)                {                    if (BuildPipeline.BuildAssetBundle(asset, null, targetPath + fileName + ".assetbundle", out crc,                       //BuildAssetBundleOptions.UncompressedAssetBundle |                       BuildAssetBundleOptions.CollectDependencies |                       BuildAssetBundleOptions.CompleteAssets,                       TargetPlatform.buildTarget))                    {                        Debug.Log("Create RoleRes Success: " + fileName);                    }                    else                        Debug.LogError("Create RoleRes Asset Error!!! " + fileName);                }                else                {                    Debug.LogError("Create RoleRes Asset Error!!! " + fileName);                }            }        }


主要方法:BuildPipeline.BuildAssetBundle(mainasset,assetarray,targetpath,options,BuildbuildtargetType)
参数mainasset是主资源,类型为object,当该参数不为空时,认为打包资源为主资源,在加载Bundle的时候可以直接取bundle对象的mainAsset属性,即为所需资源
参数assetarray是资源数组,类型为object[],可以将多个asset放入数组传入这个参数,只是在加载Bundle的时候需要用bundle对象的Load方法,例如 wwwObj.assetBundle.Load ("One"),加载该Bundle中名字为One的资源。
参数targetpath为打包路径,类型为string
参数options为打包选项,类型为BuildAssetBundleOptions
     BuildAssetBundleOptions.CollectDependencies 为包含所有依赖关系
     BuildAssetBundleOptions.CompleteAssets 为强制包含整个资源
     BuildAssetBundleOptions.DisableWriteTypeTree 为在AssetBundle中不包含类型信息。需要注意的是,如果将AssetBundle发布到web平台上,则不能使用这个选项;
     BuildAssetBundleOptions.UncompressedAssetBundle 使每个Object具有唯一的、不变的HashID,便于后续查找可以用于增量发布AssetBundle,主要用作相互依赖的资源打包,此处有坑,慎用或者不用^_^
     BuildAssetBundleOptions.UncompressedAssetBundle   不进行数据压缩。如果使用这个选项,因为没有压缩/解压的过程,AssetBundle发布和加载会更快,但是AssetBundle也会更大,导致下载变慢。
参数buildtargetType为打包平台类型,类型为BuildTarget例如BuildTarget.Android

二.加载
首先先在Assets目录下手动新建一个文件夹命名为StreamingAssets,该文件夹会被识别,其路径下的文件只能通过WWW方式加载,一般情况AssetBundle文件全部放到这个文件夹下

// 不同平台下StreamingAssets的路径    public static readonly string RawPath =    #if UNITY_ANDROID && !UNITY_EDITOR    "jar:file://" + Application.dataPath + "!/assets/";    #elif UNITY_IOS && !UNITY_EDITOR    "file://" + Application.dataPath + "/Raw/";    #elif UNITY_STANDALONE_WIN            "file://" + Application.streamingAssetsPath + "/";    #else            "file://" + Application.dataPath + "/StreamingAssets/";    #endif    void LoadFunction(){ Object obj = null;   AssetBundle ab = null;// just for res info string path = "Player/PlayerFaShi";         WWW www = new WWW(string.Format("{0}{1}.assetbundle", RawPath, path));         yield return www; if (!string.IsNullOrEmpty(www.error))         {              LogManager.Log(string.Format("LoadFunctionError, tblId: {0}, error: {1}", tblId, www.error), LogType.Fatal);          }          else          {               ab = www.assetBundle;               obj = www.assetBundle.mainAsset;//  www.assetBundle.load("xxx");           }  if(null != ab)          {               ab.Unload(false);//清内存!           }   }

对于AssetBundle的用法先介绍到这,后续补充。


三.   完

                                             
1 0
原创粉丝点击