Unity之AssetBundle原理全解

时间:2022-01-11 14:59:27

需要修改 不完善 请别细看

AssetBundle:首先我们需要对这个名称有个概念他到底是什么东西,我们构建游戏里面有音乐,贴图,材质,预设等各种资源组拼成一个好玩的游戏。这些都是AssetBundle吗,No,Unity中很简单你在对应资源窗体下面给资源上包名才算。上图;
Unity之AssetBundle原理全解
好了我们就以为可以设置成这个东西,我们就可以写打包工具Build成AB包,并且会放在一个特殊文件夹里,名字固定死了StreamingAssets.这个是我们打包之前的准备工作完毕。
下面步入打包原理正题:
不得不说我看了网上很多对AB的讲解感觉有点官方不太好理解,那么我谈AB原理之前先讲一个故事:
希望大大好好看,假如我由于技术比较牛逼,突然有一天腾讯企鹅大佬说要挖我过去上班,当然二话不说去呗。这个时候麻烦了我住的地方塞满了比较贵重的各种物品。怎么办我在新的公司需要用啊,又舍不得丢掉他们重新买。所以我就打算走快递,我就把这些物品打包在一个袋子里压得紧紧的,这个袋子我们可以看成是AssetBundle他里面有各种物品。我用了什么绝招把本来要占大空间的放入了一个小袋子,这个时候我打电话通知快递拿包给寄到我新公司。这个是不是可以看成WWW www = new WWW(url)呢。可以当然unity对游戏里的资源包进行压缩。这样有什么好处方便快递员运输啊,以及网络传输更加快。快递还真快才一天我的包就到了。我就和快递员见面拿货,等价于www.assetbundle.这样我是不是拿到了我以前打的那个包裹呢,我拿到包裹后肯定要拆包啊,这个动作就是在解压压缩包。这个就和我拆包裹不同,我解压包后其实我那个压缩包还是存在内存,这个时候等于我内存里面存在一个压缩包和解压后的包。好了我饿了。我想拿出里面的锅炒菜啊。好了既然我的包裹被拆了我是不是可以拿锅炒菜对不对,对。炒菜就直接炒了就一个锅。但是我们在游戏里,想去解压包里拿里面的比较音乐资源去播放音乐,需要通过AssetBundle.LoadAsset接口去拿到一个音乐资源。这个时候资源是如何变得。其实是我们去解压的一个总包裹里找到音乐资源。然后开了一片内存把需要的音乐资源放在这个内存,包裹里的解压文件没有任何少。
现在谈我们需要的是预设资源的情况。这个我们不能直接拿来用。而是需要Instantiate出来。这个时候是怎么进行的。和上次加载音乐文件差不多。我们先要把预设提取到内存。然后我们通过克隆的方式实例。这样内存又会多了份预设的拷贝。然后这个预设就可以显示了。完工。
现在谈卸载不用的资源,比如我们需要切换场景了。上个场景的资源如果没有卸载,会发现内存泄漏。
我们从www开始。也就是假如我们开始打算寄包裹的情景。www = null ||www.dispose. 我们通过这个方法可以释放new www占用的全部资源。www我们可以看成是一个快递员。我们寄完东西后,就需要和快递员切断一切联系,不然他天天打电话骚扰你。好了注意上面说过我们拆包裹的时候,比如取里面的锅。
我们的压缩包和拆后的包都存在。我们需要清掉他们释放内存。assetBundle.unload(false)注意这个需要和assetBundle.unload(true)区分开。前面释放的是一个压缩包和解压后的包。 后面释放压缩包和解压后的包并且还把在这个解压包提前存在其他内存的资源也给你清理了。这个情况你们可能会遇到后后面的卸载资源方法就会出现明明场景的物品本来显示突然就不见了就是因为你把那个物品依赖的资源卸载了导致的。
还有一个情况就是比如我加载的音乐资源已经播完了以后不用了啊。我们要清理掉就用Resource.UnLoadAsset(“.mp3”)这个是具体指定卸载哪个资源。还可以直接Resource.UnLoadUnusedAsset();这个接口会找提取出来的资源并且没有谁引用他就卸载掉。但是你实例化出来的也不想显示了必须卸载就必须Destory来处理。不同分工不同结果。
现在讨论AB之间的依赖:首先我们要搞清什么叫包之间有依赖关系,假如我一个预设他用了一个材质。我在给这个预设打包。我问你这个预设包在实例化出来会因为材质的原因报错吗,也就是这个时候会依赖这个材质,肯定不是。为什么因为材质并没有打成一个包。如果材质也打包了。我们预设也打包了那么我实例化预设之前必须先加载这个材质包也就是预设依赖的包,这个就是依赖打包的顺序问题。那么回到一个疑问。既然预设和材质可以打成一个包。为啥要打2个包多了依赖打包这个麻烦啊。肯定是有好处。是什么呢,整体而言减少重复打包减少计算机资源。比如2个预设都共享一个材质,如果单独给2个预设打包。就会在每个 包都有一个材质,这样我们会加载2个材质到内存,浪费内存。那么我们就给2个预设和材质分别打包成3个包。我们在用预设的时候先加载出材质包,在加载预设,在实例化就显示出了。
待续