Unity assetbundle笔记
一:AssetBundle使用流程:
1.给指定资源设置assetbundle属性
2.构建assetbundle包(打ab包),也可以用ab浏览工具打包
BuildPipeline.BuildAssetBundles(目录,BuildAssetBundleOptions,BuildTarget);//除了在指定目录下生成ab包,还会自动在目录下生成与文件夹同名的ab包,以及Manifest文件,可用来加载依赖关系
3.上传AB包到服务器
4.加载AB包,和包中资源(加载:资源将会存储到设备运行内存中)
AssetBundle ab = AssetBundle.LoadFormFile("ab包相对路径,要写出ab包后缀");//load到内存中 GameObject go = ab.LoadAsset<GameObject>("prefab名字"); Instantiate(go);
二:ab包分组策略:
1.把经常更新的资源放在单独的包里,跟不常更新的资源分开
2.把需要同时加载的资源放在一个包里
3.把其他包所共享的资源放在一个包里,比如场景的shader,mat(需要用到依赖打包)
4.把一些需要同时加载的小资源放在一个包里
5.如果同一个资源有两个版本,可以通过后缀来区分
三:依赖打包:
1.unity自动会加载依赖的资源,比如模型共享的材质,直接把材质资源打包,模型打包后文件变小,而且会自动加载所依赖的资源。
2.依赖的信息在Manifest文件中
3.ab包有依赖关系时,必须加载被依赖的ab包。
四:API讲解(©SIKI)
1.打ab包的API
2.加载ab包的API:
3.LoadFormMemory()
IEnumerator Start(){//异步加载 AssetBundleCreateRequest request = AssetBundle.LoadFormMemoryAsync( File.ReadAllBytes("资源路径")); yield return request; AssetBundle ab = request.assetBundle; } void Start( ){//同步加载 AssetBundle ab = AssetBundle.LoadFormMemory(File.ReadAllBytes("路径")); }
4.LoadFormFile()
IEnumerator Start(){//异步加载 AssetBundleRequest request = AssetBundle.LoadFormFileAsync("包路径"); yield return request; AssetBundle ab = request.assetBundle; } void Start(){//同步加载 AssetBundle ab = AssetBundle.LoadFormFile("包路径"); }
5.UnityWebRequest
using UnityEngine.NetWorking IEnumator Start(){
//本地地址 string url = @"file:///E:\路径名字\xxx.assetBundle";
//远程地址
string url2 = @"http://www.域名.com/路径名称/xxx.assetBundle";
UnityWebRequest request = UnityWebRequest.GetAssetBundle(url); yield return request.Send();//发送请求并等待下载完成 //加载方式一 AssetBundle ab = DownLoadHandlerAssetBundle.GetContent(request); //加载方式二 AssetBundle ab = (request.downLoadHandler as DownLoadHandlerAssetBundle).assetBundle; }
6.加载ab包中的资源:
T objectFromBundle = bundleObject.LoadAsset<T>(assetName);//加载一个资源 Unity.Object[] objectArray = loadedAssetBundle.LoadAllAssets();//加载所有资源
五:加载Manifest文件,并读取依赖包
AssetBundle assetBundle = AssetBundle.LoadFromFile(manifestFilePath);//注意这里的manifestFilePath是指自动生成的,与文件夹同名的那个ab文件。不是manifest文件!!臭老外文档瞎几把乱写 AssetBundleManifest manifest = assetBundle.LoadAsset<AssetBundleManifest>("AssetBundleManifest"); string[] dependencies = manifest.GetAllDependencies("xxx.assetBundle"); //参数是ab文件全名 foreach(string dependency in dependencies) { AssetBundle.LoadFromFile(Path.Combine(assetBundlePath, dependency)); }
六:卸载内存中的ab包
1.AssetBundle.Unload(bool);
2.true:全部卸载,会造成资源引用丢失
3.false:在使用中asset不会卸载,会造成内存浪费
4.使用Resource.UnloadUnusedAssets()卸载内存中没被使用的个别asset(比如材质,贴图等等)
5.正确的卸载方法:场景切换的时候Unload(false)部分卸载,U3D自动调用Resource.UnloadUnusedAssets(),之后再手动调用一次确保内存没有浪费
七:TIPS
1.sprite2d类型的资源最后会根据packing tag打包到不同的图集(sprite atlas)中,推荐相同图集里的图片打包到一个ab包里
2.UnityAssetBundle Broswer Tool 插件
3.ab包引用以及重复打包:A dependency does not occur if the UnityEngine.Object
contains a reference to a UnityEngine.Object
that is not contained in any AssetBundle. In this case, a copy of the object that the bundle would be dependent on is copied into the bundle when you build the AssetBundles.(比如一个打包一个模型prefab,如果模型的mat没有被打包,那么打包的时候会将mat复制进去)
4.加载ab包某一资源时必须要加载其依赖的ab包(In this example, before loading the Material from Bundle 1, you would need to load Bundle 2 into memory. It does not matter which order you load Bundle 1 and Bundle 2, the important takeaway is that Bundle 2 is loaded before loading the Material from Bundle 1)