unity3d unity5.0unity asset bundlebundlemanifest包含哪些数据

匿名用户不能发表回复!|
每天回帖即可获得10分可用分!小技巧:
你还可以输入10000个字符
(Ctrl+Enter)
请遵守CSDN,不得违反国家法律法规。
转载文章请注明出自“CSDN(www.csdn.net)”。如是商业用途请联系原作者。AssetBundle资源打包 Unity5.0
for (int i = 0; i & objs.L i++)
targetDir = path +&/&+ GetBuildTargetPath(buildTargetPlatform);
if (!Directory.Exists(targetDir)) Directory.CreateDirectory(targetDir);
targetPath = targetDir + Path.DirectorySeparatorChar + objs&i&.name + extensionN
if (BuildPipeline.BuildAssetBundle(objs&i&, null, targetPath, BuildAssetBundleOptions.CollectDependencies, buildTargetPlatform))
Debug.Log(&打包成功:& + objs&i&.name);
this.ShowNotification(new GUIContent(&打包& + objs&i&.name + &失败&));
}BuildPipeline.BuildAssetBundle旧有方式如何修改成5.0可调用的方式,是否不能一个一个打包?
有人使用新版的调用过吗?
要评论请先&或者&Unity&AssetBundle&学习、分析及总结
本文是学习、和阅读Unity代码的总结
转自:/elang/p/5676590.html
AssetBundle基本知识
1.&AssetBundle由两部分组成:头部(header)数据部分(data
头部保存了版本号、数据类型、文件信息、是否压缩等这些描述信息。
文件信息记录了数据部分里面的所有单个资源的文件名以及在整个AssetBundle中文件offset和size,通过这个信息可以直接获取到AssetBundle中的某一个文件的数据。从Unity5.3版本开始这部分数据会单独生成一个AssetBundle同名的.manifest文件。
数据块保存了在build
AssetBundle时候标记的textures、prefabs、materials等这些资源文件
2.&生成的AssetBundle内容文件可选的格式
Uncompressed(未压缩)
LZ4 (Unity 5.3版本开始支持)
3.&项目里面尽量通过AssetBundle的方式来分发资源,不推荐把资源文件全部放到Resources目录中。对比如下:
大量的资源放到Resources目录中当要加载其中某些资源的时候会造成更长的搜索资源的时间
AssetBundle文件可以按需来加载和卸载便于管理内存
AssetBundle文件可实现在线下载,便于资源更新
生成AssetBundle文件
生成AssetBundle Unity提供的API如下:
public static AssetBundleManifest BuildAssetBundles (string outputPath, BuildAssetBundleOptions assetBundleOptions, BuildTarget targetPlatform){}
其中我们主要看第二个参数BuildAssetBundleOptions,它定义如下:
public enum BuildAssetBundleOptions
UncompressedAssetBundle = 1,
ChunkBasedCompression = 256,
StrictMode = 512,
OmitClassVersions = 1024
这几种类型说明:
ChunkBasedCompression这个选项在Unity5.3版本开始添加了,它支持把AssetBundle中每个组成对象build为LZ4格式的数据(5.3版本之前是不支持的)。这样的话就带来了一个很大的好处,我们在加载AssetBundle的时候不需要解压整个AssetBundle来读取我们需要加载AssetBundle中的某个对象的数据,可以加快读取Asset的速度同时也节省了很多内存。
UncimpressedAssetBundle这个选项使用为压缩的格式。这样省去了加载AssetBundle或者实例化Asset的时候解压缩的时间,但是build出来的AssetBundle的文件大小会比较大
其他选项使用LZMA格式的压缩格式来生成AssetBundle文件。这种格式其实压缩率是最大的,build出来的AssetBundle文件大小最小,但是这种格式的AssetBundle的读取效率(时间,内存)比不上使用LZ4格式生成的AssetBundle。不过在5.3版本之前只有这一种压缩格式可选
总结:&如果使用的Unity是5.3版本或更高级版本,推荐使用ChunkBasedCompression压缩格式
加载AssetBundle对象
在Unity5.3版本Unity对加载AssetBundle对象的API做了修改,
主要有三种方式加载/生成AssetBundle的API(前两种这里省去带crc参数的API):
public static AssetBundle LoadFromMemory(byte[] binary);
public static extern AssetBundleCreateRequest LoadFromMemoryAsync (byte[] binary);
public static AssetBundle LoadFromFile (string path);
public static AssetBundleCreateRequest LoadFromFileAsync (string path);
public static WWW LoadFromCacheOrDownload(string url, int version, uint crc = 0);
LoadFromMemory(Async)这个API在Unity5.3版本名字改为CreateFromMemory。虽然名字改了但是它的功能没有变化,先看下怎么使用(方法直接拷贝):
WWW www = new WWW (url);
yield return
AssetBundleCreateRequest assetBundleCreateRequest = AssetBundle.CreateFromMemory (www.bytes);
yield return assetBundleCreateRequest;
AssetBundle assetBundle = assetBundleCreateRequest.assetBundle;
想象一下CreateFromMemory方法接受的参数是一个AssetBundle的原始数据然后返回了一个AssetBundleCreateRequest包装的AssetBundle。那么AssetBundle是直接的数据是成员变量的引用指向www.bytes数据吗(这样的话是最省内存的)?
还是会自己拷贝一份www.bytes数据。显然使用成员变量引用指向www.bytes是行不通的,因为www的内存只要一释放那么AssetBundle这个对象肯定就使用不了了。进一步证实我们可以看CreateFromMemory这个方式的实现:
[WrapperlessIcall]
[MethodImpl(MethodImplOptions.InternalCall)]
public static extern AssetBundleCreateRequest CreateFromMemory(byte[] binary);
看到方法很发现它真正调用的是C++层的CreateFromMemory方法,那我们继续看C++层
CUSTOM static AssetBundleCreateRequest CreateFromMemory(byte[] binary)
if (!binary)
return SCRIPTING_NULL;
int dataSize = GetScriptingArraySize(binary);
UInt8* dataPtr = Scripting::GetScriptingArrayStart(binary);
AsyncOperation* req = new AssetBundleCreateRequest(dataPtr, dataSize);
return CreateScriptingObjectFromNativeStruct(MONO_COMMON.assetBundleCreateRequest,req);
binary(也就是www.bytes数据)数据最终被C++层的AssetBundleCreateRequest对象包裹,然后再通过CreateScriptingObjectFromNativeStruct方法转换成Mono对象返回给了Mono层。在继续跟踪binary数据的去向的时候我们发现最终Unity通过这个数据创建了一个UnityWebStream对象,而这个对象是作为AssetBundleCreateRequest的成员变量存在的。在创建这个UnityWebStream对象的过程中Unity终于使用了binary数据,首先解析了头部数据然后再把数据部分(data
segment)通过memorycpy拷贝到了UnityWebStream对象在非托管内存中申请的内存空间上,而且如果数据是LZMA格式的话,Unity还会对其进行解压。
while(bytesCopied & size)
int bytesToCopy = std::min&&span class="dt" style="margin: 0 padding: 0"&int&(size - bytesCopied, kDownloadBufferSize - buf.bytesUsed);
memcpy(buf.mem + buf.bytesUsed, (UInt8*)data + bytesCopied, bytesToCopy);
buf.bytesUsed += bytesToC
上面data数据就是我们传入的binary数据。进过上面分析我们可以确认使用CreateFromMemory这个方法来创建AssetBundle肯定会消耗两倍与AssetBundle数据的内存空间。
LoadFromFile这个API在Unity5.3之前的版本方法名为CreateFromFile,同样这个API的功能并没有变。这个API支持读取未压缩的和LZ4格式的AssetBundle文件,但是LZMA格式文件经过加压之后任然可以读取。官方文档中有一句话是这样描述的:
This is the fastest way
to load an AssetBundle
使用LoadFromFile方法的时候在手机或者Pad设备上的加载AssetBundle的时候仅仅加载AssetBundle的头信息,至于AssetBundle的数据部分(data
segment)并不会加载到内存中,然后当我们使用Load(Async)来加载AssetBundle中的某一个Asset的时候找到这个Asset对应在AssetBundle文件中的位置并仅读取这部分数据。这样的话就可以节省非常多的内存空间加载的速度自然会变快了。
LoadFromCacheOrDownload使用这种加载的话会缓存一份解压之后的AssetBundle数据缓存到本地(不管是从网络下载还是加载本地的AssetBundle都会缓存)。当第二次加载的时候在版本号不变的情况下LoadFromCacheOrDownload会加载本地的缓存,但是只会读取BundleHeader和FullHeader数据。iOS平台下AssetBundle缓存的路径:
application.persistentdatapath + "../Library/UnityCache/Shared/*"
当存在了缓存文件之后再次使用LoadFromCacheOrDownload方法加载的时候它的工作方法其实和LoadFromFile的工作方式一样了,它只会把AssetBundle数据的头部信息加载到内存中,等我们要加载AssetBundle中的某个Asset的时候才会去磁盘上读取对应的部分的数据。那么它和LoadFromFile的不同之处在哪里呢?不同之处就在于这是一个WWW的方法。和LoadFromMemory一样它的原始数据来自WWW,
WWW在加载这个原始数据时同样会拷贝一份数据在非托管的内存空间上。这样的话就会造成两倍的内存开销,不过幸好LoadFromCacheOrDownload第一次加载会缓存到本地之后就没有这个额外的内存消耗了。
总结:&如果使用的Unity是5.3之前的版本那么最好使用LoadFromCacheOrDownload来加载AssetBundle。但是如果使用的是5.3版本及高版本则最好使用LoadFromFile(Async)这个方法来加载AssetBundle。
卸载AssetBundle对象
1.卸载的方法
AssetBundle有一个Unload的成员方法来卸载AssetBundle资源,首先我们看下Unload的方法声明:
public extern void Unload (bool unloadAllLoadedObjects);
Unload方法带有一个bool类型的unloadAllLoadedObjects参数,这儿参数的作用Unity官方的API也有详细说明。当unloadAllLoadedObjects为true的时候所有的从AssetBundle中加载的对象和AssetBundle本身将会被卸载。
2.实例化的资源清理问题
当unloadAllLoadedObjects为false的时候只会卸载AssetBundle本身,从AssetBundle中实例化的对象是不会卸载的。这些已经实例化的对象在依赖的AssetBundle被Unload(false)卸载的时候它们之间引用也就断了,这个时候如果Load之前被卸载的那个AssetBundle的重新实例化里面的对象和之前的对象就没有任何关系了,就算之前的对象还存在于内存当中。举个例子:现在有AssetBundle文件A,A里面包含了一个material
m。然后我们进行一下步骤:
Load AssetBundle A得到对象A1,从A1中实例化m得到m1
通过Unload(false)卸载A1 (此时m1还在内存当中)
再次Load AssetBundle
A得到对象A2,从A2中实例化m。此时会得到新的一个实例化对象m2就算m1还是内存当中,因为此时m1和A2没有任何关系。那么m1这个对象就需要我们自己去销毁了。
从上面例子我们可以看出使用Unload(false)卸载AssetBundle的话很容易造成内存当中同一个Asset会有几份拷贝,这样会浪费一定的内存。
已投稿到:
以上网友发言只代表其个人观点,不代表新浪网的观点或立场。unity5_AssetBundle_百度文库
两大类热门资源免费畅读
续费一年阅读会员,立省24元!
unity5_AssetBundle
上传于|0|0|文档简介
&&unity5新的AssetBundle系统介绍PPT
阅读已结束,如果下载本文需要使用5下载券
想免费下载本文?
定制HR最喜欢的简历
下载文档到电脑,查找使用更方便
还剩53页未读,继续阅读
定制HR最喜欢的简历
你可能喜欢

我要回帖

更多关于 unity5.x assetbundle 的文章

 

随机推荐