学习一下AssetBundle相关的知识。
-
打包
关于Assetbundle相关的API,可以参考Unity的官方文档(点击这里) 。关于打包的API,官方使用的是BuildPipeline类中的BuildAssetBundles(string outputPath, BuildAssetBundleOptions assetBundleOptions, BuildTarget targetPlatform)方法。该方法的第一个参数是输出路径,第二个参数是打包选项,一般选择UncompressedAssetBundle(不压缩数据)即可,第三个参数是打包平台,win平台是StandaloneWindows,安卓平台就是Android等等。在编辑器下面撰写脚本,调用该API即可。
-
打包出的资源
打包出来的每个资源都会附带一个manifest文件,该文件记录了资源的所有依赖资源的信息和资源的信息。同时,会为当前的目录生成一个assetbundle资源和对应的manifest文件,这个manifest文件中记录则是该文件夹下面所有资源,及其依赖的信息。
-
从本地加载AssetBundle资源
加载本地的资源和加载服务端的资源所使用的API有些许的不同。这里主要使用两个API。第一个就是LoadFromFile方法,这是从本地中加载AssetBundle的方法,其接受的参数是AssetBundle的路径。然后再用LoadAsset方法从AssetBundle中加载资源,其参数是需要加载的资源的名字(实际名字,非assetbundle标签名,并且名字不分大小写)。另外,该方法有一个泛型参数,可以用于指定资源的类型。还有一个方法是LoadAllAssets,这个可以直接加载该指定AssetBundle中的所有资源,返回一个Object数组。这里的同一个AssetBundle资源指的是assetbundle标签名相同的资源,这样的资源会打成同一分bundle资源,但是内部的资源却是不止一份。
加载资源的时候,如果资源的依赖资源是分开打包的,那么,依赖资源也必须被加载出来,否者会出现材质丢失的情况。依赖资源是保存在资源对应的manifest中的,另外,还有一份保存在资源文件夹的manifest中的。可以使用这个总的资源列表文件来加载对应资源的依赖资源。我也曾尝试过使用资源对应的manifest文件来读取依赖资源,不过发现,该manifest不能使用LoadFromFile方法加载出来,不知道是什么原因。
-
从内存中加载AssetBundle资源
从内存加载使用的API是LoadFromFileAsync,该方法是异步的,当然也有同步方法,从本地加载的LoadFromFile也有异步方法。LoadFromFileAsync方法返回AssetBundleCreateRequest类型,其属性assetBundle就是所需要的AssetBundle资源。该方法是异步的,所以要使用协程来运行。
-
从服务端下载AssetBundle资源
从服务器上下载使用的是WebRequest 方法,不过该方法只在Unity5.3及以上版本中使用。之前的可以使用WWW.LoadFromCacheOrDownload来下载。使用WebRequest下载,分为两步,先使用UnityWebRequestAssetBundle类中的GetAssetBundle方法,该方法返回一个UnityWebRequest对象,使用Send方法请求下载,然后使用DownloadHandlerAssetBundle.GetContent方法接受UnityWebRequest对象,返回AssetBundle资源。
同样的,也可以直接从UnityWebRequest对象中获取AssetBundle对象,具体方法如下,获取下载器对象downloadHandler,通过下载器对象的属性来获取Bundle资源:
对于下载的数据,可以使用下载器的data属性来获取字节数组,然后进行写入保存。
-
卸载资源
卸载资源可是使用AssetBundle类的成员方法Unload()。 当参数为false时,表示卸载包中没有被使用的资源(包中有多个资源,有些在使用,有些没有被使用)。这种情况下,如果包体重新被加载后,则包体和原先没有被删除的资源没有任何关联了,就会出现某些资源会在内存中存在两份的情况(一份之前卸载的包体加载出来的,一份包体重新加载出来的)。相应的,参数为true时,表示将整个资源卸载,这种情况下,如果没有确认所以资源是否不再被使用时,有可能造成资源丢失。