Unity AssetBundle packaging pit

This article conducts a relatively comprehensive analysis from all aspects of AssetBundle packaging, use, management and memory usage, and provides guidance and guidance on filling some pitfalls in the use of AssetBundle!
AssetBundle is the resource management method recommended by Unity. The official list lists advantages such as hot update, compression, flexibility, etc. However, the pit of AssetBundle is very deep. There are many hidden details that you need to be very cautious in using, and you will fall into it if you are not careful. Deep pit, packaging is not planned well, 20MB resources are "compressed" to 30MB, or a large number of packages lead to various inefficiencies in packaging and loading, or inexplicable loss of association, or memory explosion, and various loading failures. I have studied a lot of articles about AssetBundle online, but every time I read them, I still have a lot of questions, so I can only answer the questions in my mind through practice. To ensure the accuracy of the results, the following test is done under the editor, Windows, Tests and comparisons have been conducted under IOS.
First of all, why should you choose AssetBundle? Even though it has various benefits, the general reason for choosing AssetBundle is to do hot updates, dynamically update game resources, or the resources under your Resource exceed its limit (2GB or 4GB?). If you don't have such a need, then I suggest you not to use this bad thing, it's annoying~~
After you select AssetBundle, and before I start spraying AssetBundle, we need to give a brief introduction to the workflow of AssetBundle:
AssetBundle can be divided into packaging AssetBundle and using AssetBundle
Packaging requires writing some simple code under UnityEditor to take out the resources you want to package, and then call the packaging method to package.
When using it, you need to use WWW to load the Bundle, and then use the loaded Bundle to load resources.
WWW w = new WWW("file://" + Application.streamingAssetsPath + "/Test.assetbundle"); myTexture = w.assetBundle.Load("Test")
【1. Packing】
Next let’s take a look at packaging:
1. Collection of resources
Before packaging, we can automatically package by traversing the directory. We can selectively package some directories into a Bundle. We can also use various configuration files to manage resources, and we can also use directory specifications to manage this.
I use a directory specification to classify resources into several large modules: public, in-game, and outside the game, and then use a set of simple naming specifications to guide packaging, such as using OBO (OneByOne) as the directory suffix. Guide to package all resources in the directory independently. By default, they are packaged into one package. Use the Base prefix to indicate that this is a public package. Other directories in the same directory need to depend on it.
Use Directory's GetFiles and GetDirectories to easily obtain the directory and the files in the directory.
Directory.GetFiles("Assets/MyDirs", "*.*", SearchOption.TopDirectoryOnly); Directory.GetDirectories(Application.dataPath + "/Resources/Game", "*.*", SearchOption.AllDirectories)
2. Resource reading
GetFiles搜集到的资源路径可以被加载,加载之前需要判断一下后缀是否.meta,如果是则不取出该资源,然后将路径转换至Assets开头的相对路径,然后加载资源
tring newPath = "Assets" + mypath.Replace(Application.dataPath, ""); newPath = newPath.Replace("\\", "/"); Object obj = AssetDatabase.LoadMainAssetAtPath(newPath)
3.打包函数
我们调用BuildPipeline.BuildAssetBundle来进行打包:
BuildPipeline.BuildAssetBundle有5个参数,第一个是主资源,第二个是资源数组,这两个参数必须有一个不为null,如果主资源存在于资源数组中,是没有任何关系的,如果设置了主资源,可以通过Bundle.mainAsset来直接使用它
第三个参数是路径,一般我们设置为  Application.streamingAssetsPath + Bundle的目标路径和Bundle名称
第四个参数有四个选项,BuildAssetBundleOptions.CollectDependencies会去查找依赖,BuildAssetBundleOptions.CompleteAssets会强制包含整个资源,BuildAssetBundleOptions.DeterministicAssetBundle会确保生成唯一ID,在打包依赖时会有用到,其他选项没什么意义
第五个参数是平台,在安卓,IOS,PC下,我们需要传入不同的平台标识,以打出不同平台适用的包,注意,Windows平台下打出来的包,不能用于IOS
在打对应的包之前应该先选择对应的平台再打包
4.打包的决策
在打包的时候,我们需要对包的大小和数量进行一个平衡,所有资源打成一个包,一个资源打一个包,都是比较极端的做法,他们的问题也很明显,更多情况下我们需要灵活地将他们组合起来
打成一个包的缺点是加载了这个包,我们不需要的东西也会被加载进来,占用额外内存,而且不利于热更新
打成多个包的缺点是,容易造成冗余,首先影响包的读取速度,然后包之间的内容可能会有重复,且太多的包不利于资源管理
哪些模块打成一个包,哪些模块打成多个包,需要根据实际情况来,例如游戏中每个怪物都需要打成一个包,因为每个怪物之间是独立的,例如游戏的基础UI,可以打成一个包,因为他们在各个界面都会出现
PS.想打包进AssetBundle中的二进制文件,文件名的后缀必须为“.bytes”
【二,解包】
【二,解包】
tring.Format("file://{0}/{1}", Application.streamingAssetsPath, bundlePath)
在安卓下路径不一样,如果是安卓平台的本地Bundle,需要用jar:file://作为前缀,并且需要设置特殊的路径才能加载
tring.Format("jar:file://{0}!/assets/{1}", Application.dataPath, bundlePath)
传入指定的URL之后,我们可以用WWW来加载Bundle,加载Bundle需要消耗一些时间,所以我们一般在协同里面加载Bundle,如果加载失败,你可以在www.error中得到失败的原因

Guess you like

Origin blog.csdn.net/qq_25189313/article/details/77930340