目录
一.BuildAssetBundleOptions 的枚举类型含义
(1).AssetBundle.LoadFromFile,从本地磁盘上同步加载 (这种加载方式是最快的)
(2).AssetBundle.LoadFormFileAsync,从本地磁盘上异步加载
(3).AssetBundle.LoadFromMemory,从内存中同步加载。
(4).AssetBundle.LoadFromMemoryAsync,从内存中异步加载。
(2). Resources.UnloadUnusedAssets 卸载掉无引用的资源
(3). Reources.UnloadAsset(Object) 卸载指定的资源
(4). GC.Collect() (unity自带的垃圾回收)
(1).加载卸载 搞引用计数器和 时间管理器 维护已加载的列表安全稳定,来尽量减小内存压力
(1).在加载新场景时 AssetBundle文件自身的内存镜像 必须要用Unload来释放
(2). 包的颗粒度一个资源一个包,每个包的包名就是 相对路径,这样包名不会重复,全是独一份的
4.第一次Instaniate一个Prefab的时候都会卡一下
1.m_manifest.GetAllDependencies(abName) ,去获取某个ab资源的依赖时,这个包名一定是它的 assetBundleName
2.当大量(几百个)AssetBundle加载的时候(可能是WWW加载的时候,也可能是AssetBundle.LoadAsset的时候),Android手机上会闪退。
自我记录笔记,应该解释的超详细了,如有偏颇望大佬们指教一二.
一.BuildAssetBundleOptions 的枚举类型含义
public enum BuildAssetBundleOptions
{
None = 0,//打包assetBundle时,没有任何特殊选项的
UncompressedAssetBundle = 1,//打包assetBundle时,不压缩数据(意味着assetbundle会更大)
CollectDependencies = 2,//包括所有依赖关系
CompleteAssets = 4,//强制包含整个资源
DisableWriteTypeTree = 8,//在AssetBundle中不包含类型信息,发布web平台时,不能使用该项
DeterministicAssetBundle = 16,//使每个Object具有唯一不变的hash id,可用于增量式发布AssetBoundle
ForceRebuildAssetBundle = 32,//强制重新build所有的AssetBoundle
IgnoreTypeTreeChanges = 64,//执行增量检测时,忽略TypeTree的变化。
AppendHashToAssetBundleName = 128,//将hash加到AssetBoundle名中
ChunkBasedCompression = 256,//创建AssetBundle时使用LZ4压缩。默认情况是Lzma格式,下载AssetBoundle后立即解压。
StrictMode = 512,//如果生成过程中报告了任何错误,则不会build成功
DryRunBuild = 1024,//做一个演练build
DisableLoadAssetByFileName = 4096,//资源包名禁用LoadAsset
DisableLoadAssetByFileNameWithExtension = 8192资源包拓展名禁用LoadAsset
}
1.解释
(1).最常用的三种:
- BuildAssetBundleOptions.None:默认构建AssetBundle的方式。使用LZMA算法压缩,此算法压缩包小,但是加载时间长,而且使用之前必须要整体解压。解压以后,这个包又会使用LZ4算法重新压缩,这样这种包就不要对其整体解压了。(也就是第一次解压很慢,之后就变快了。)
- BuildAssetBundleOptions.UncompressedAssetBundle:不压缩数据,包大,但是加载很快。
- BuildAssetBundleOptions.ChunkBaseCompression:使用LZ4算法压缩,压缩率没有LZMA高,但是加载资源不必整体解压。这种方法中规中矩,一般比较常用。(折中方式)
(2).其余的几种简单介绍:
-
BuildAssetBundleOptions.DisableWriteTypeTree:不会在AssetBundle中包含类型信息。
-
BuildAssetBundleOptions.DeterministicAssetBundle:使用存储在Asset Bundle中的对象的id的哈希构建Asset Bundle。
-
BuildAssetBundleOptions.ForceRebuildAssetBundle:强制重建Asset Bundles。
-
BuildAssetBundleOptions.IgnoreTypeTreeChanges:执行增量构建检查时忽略类型树更改。
-
BuildAssetBundleOptions.AppendHashToAssetBundleName:将哈希附加到assetBundle名称。
-
BuildAssetBundleOptions.StrictMode:如果在其中报告任何错误,则不允许构建成功。
-
BuildAssetBundleOptions.DryRunBuild:不实际构建它们。
-
BuildAssetBundleOptions.DisableLoadAssetByFileName:通过文件名禁用Asset Bundle的加载。
-
BuildAssetBundleOptions.DisableLoadAssetByFileNameWithExtension:通过带扩展名的文件名禁用Asset Bundle 的加载。
2.总结
一般都是默认 ChunkBasedCompression 是最常用的
多版本维护的包体 推荐再添加 DeterministicAssetBundle
二.AssetBundle的加载
1.加载资源方式
(1).AssetBundle.LoadFromFile,从本地磁盘上同步加载 (这种加载方式是最快的)
这个对于不大的包体 和 加载压力小的项目最常用
参数为 该资源全路径 , 加载出来的只是 该ab在内存的复制镜像, 我们再从里面读取数据什么的都是在操作镜像文件
private void LoadFormFileExample()
{
//括号内 为资源的的 全路径!
AssetBundle ab = AssetBundle.LoadFromFile(rootPath+"AB路径");
if (ab!=null)
{
GameObject obj = ab.LoadAsset<GameObject>("cube");
Instantiate(obj);
}
ab.Unload(false);
}
(2).AssetBundle.LoadFormFileAsync,从本地磁盘上异步加载
使用协程
IEnumerator LoadFormFileAsyncExample()
{
AssetBundleCreateRequest request= AssetBundle.LoadFromFileAsync(rootPath + "AB路径");
yield return request;
AssetBundle ab = request.assetBundle;
if (request == null)
{
yield break;
}
AssetBundleRequest abRequest = ab.LoadAssetAsync<GameObject>("cube");
yield return abRequest;
GameObject obj = abRequest.asset as GameObject;
Instantiate(obj);
ab.Unload(false);
}
(3).AssetBundle.LoadFromMemory,从内存中同步加载。
private void LoadFormMemoryExample()
{
AssetBundle ab = AssetBundle.LoadFromMemory(File.ReadAllBytes(rootPath + "cube"));
if (ab!=null)
{
GameObject obj = ab.LoadAsset<GameObject>("cube");
Instantiate(obj);
}
}
(4).AssetBundle.LoadFromMemoryAsync,从内存中异步加载。
IEnumerator LoadFormMemoryAsyncExample()
{
AssetBundleCreateRequest abcr=AssetBundle.LoadFromMemoryAsync(File.ReadAllBytes(rootPath + "ab"));
yield return abcr;
AssetBundle ab = abcr.assetBundle;
if (ab==null)
{
yield break;
}
AssetBundleRequest abRequest = ab.LoadAssetAsync<GameObject>("cube");
yield return abRequest;
GameObject obj = abRequest.asset as GameObject;
Instantiate(obj);
ab.Unload(false);
}
2.Manifest ,依赖关系加载
依赖加载: 在生成AB包时,打包AB的根目录会产生一个于文件夹同名的清单列表,这里记录所有AB包的信息,加载时先获取此清单列表,获取指定AB包的依赖关系信息,按需加载。
这是固定写法,代码为:
AssetBundleManifest manifest = ab.LoadAsset<AssetBundleManifest>("AssetBundleManifest");
该ab是总包体的大ab
情景举例:当场景中多个预制体公用一个材质时,这种情况就可以将Material就可以单独打包,这样的好处就是减少AB包的大小,否则的话就会出现每个预制体打包时会将Material打包进去,资源的重复并且AB包的内存过大。这样打包就会产生依赖关系,在AB包加载时,如果AB包产生依赖关系的话,要将所依赖的AB包先加载出来,在加载索要加载的对象,否则会造成丢失的情况。