您的位置:首页 > 移动开发 > Unity3D

unity AssetBundles

2016-03-14 22:32 393 查看

一、什么是AssetBundle

AssetBundle是一种使用LZMA压缩方式压缩的资源文件。你可以理解成就是一种压缩文件就行了。导出时压缩然后下载到本地解压使用。

二、什么是AssetBundle依赖

这个我们可以举个例子方便理解。假设我们创建一个cube物体命名obj1,然后再创建一个材质Material命名m1。把m1l赋值给obj1。这时他们就有了依赖关系obj1要是想正常显示必须要先加载m1。关系如图:



三、设置和打包

在project中选中要打包的文件,然后Inspector中设置AssetBundle名字(注意AssetBundle设置区域不明显刚开始需要拉开,我最初就是找了半天也没找到

)当然你也可以new一个AssetBundle名字。



不同资源选择相同名字,会打包成同一份Bundle。有些资源适合打包成同一份资源,有的需要单独打包,一般的情况是对于使用模型相同,绑定的脚本或者其它属性不同时,这些资源需要打包成同一份,这样可以减少总bundle的大小,不相关联的可以单独打包。(注:脚本不能打包,但是打包的bundle可以引用脚本,确保脚本在assets中即可)。
设置名字以后开始编写脚本进行打包了。主要执行命令BuildPipeline.BuildAssetBundles();具体参数参考官网,这里不详细说明。简单给出Android示例代码

MenuItem("Assets/Android")]
static void BuildAssetBundlesAndroid() {
BuildPipeline.BuildAssetBundles("Assets/bundle", BuildAssetBundleOptions.None, BuildTarget.Android);\\名录要先存在否则会报错
}
这时选择菜单栏Assets,中Android即可编译Android平台的资源。

四、加载和处理依赖

从网络加载倒是很简单,如果不想重复 下载可以使用www的LoadFromCacheOrDownload。具体使用官网查询这里不详细说明了。从www中得到assetBundle,然后assetBundle.LoadAsset(“name”)根据名字得到object,再然后转换成自己打包前的资源类型。示例代码如下:
<span style="white-space:pre">	</span>WWW www = new WWW("http://xxx/xx");
yield return www;
AssetBundle bundle = www.assetBundle;
Instantiate(bundle.LoadAsset("obj1"), new Vector3(0,0,0), Quaternion.identity);


上面是没有资源依赖,或者是本该依赖的资源都被打成一个包了。但是如果有依赖关系,打出资源还不在不同一个包下面怎么办呢,打出资源包的时候你有没有注意到会多出一个.manifest文件,此文件记录了依赖关系。这里凡是含有.mainfest的文件都是给我们看的,方便检查导出依赖关系是否正确,实际使用的都是没有.mainfest文件。打出资源包会生成一个跟文件夹名相同文件,这个文件记录所有依赖关系,处理依赖关系的时候,要先加载它,获取将要得到物体的依赖文件,先把依赖文件下载下来并加载,然后再下载要得到的物体。示例代码如下:
<span style="white-space:pre">	</span>WWW w = new WWW("http://xxx/xxbundle");
yield return w;
AssetBundleManifest assetMainfst = (AssetBundleManifest)w.assetBundle.LoadAsset("AssetBundleManifest");
string[] name = assetMainfst.GetAllDependencies("aa");  //导出的资源名
for (int i=0; i< name.Length; i++) {
Debug.Log("=====>"+name[i]);  //这里需要先根据名字去加载依赖资源,这里我没写,很简单的。依据以上示例这里name是m1导出资源名因为obj1依赖m1
}

WWW www = new WWW("http://xxx/xx");
yield return www;
AssetBundle bundle = www.assetBundle;
Instantiate(bundle.LoadAsset("obj1"), new Vector3(0,0,0), Quaternion.identity);


五、AssetBundle内存理解与管理

借助WWW下载或者LoadFromAcacheOrDownload下载加载AssetBundle后,内存中会有对应AssetBundle区域当使用LoadAseet得到物体后,内存中还会拷贝一份,这样就浪费宝贵内存。示意图如下:



所以是使用完AssetBundle后要释放,对load出来的资源多数是prefab,可以进行destroy()函数销毁。
AssetBundle卸载资源方式是unload(bool);
1、当参数是false时会把压缩数据释放掉,对于已经Load出来的资源不会释放。
2、当参数是true时,把压缩数据释放掉的同时,也会把Load出来的资源释放掉。
当有依赖关系时,举例说明,A assetbundle依赖 B assetbundle,如果B assetbundle不管用哪种方式释放,A都将映射不到B。所以会导致依赖出错。所以何时释放自己要把握好,我一般操作方式是,先加载被依赖的bundel,然后在加载bundle,load出资源后,给他们Bundle卸载unload(false)。对于被依赖bundle特别多使用频率较高的bundle不会进行及时释放。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: