Unity打包(apk,assetbundle)与资源加载
项目构建模板:jeason1997/UnityBuildTemplate: Unity项目构建模板,包括AssetBundle的构建 (github.com)
参考:unity3d:Assetbundle模拟加载,同步加载,异步加载,依赖包加载,自动标签,AB浏览器,增量打包_四夕立羽的博客-CSDN博客_unity 增量打包
1.通过命令行参数后台启动unity,并指定执行某个编辑器脚本,来实现静默打包。
-quit -batchmode -projectPath $ProjectPath -executeMethod JenkinsBuilder.BuildApp -logFile JenkinsBuildUnity.log PublishPlatform-$PublishPlatform
projectPath:工程路径
executeMethod:Unity编辑器里的脚本,哪个类的哪个函数(静态)
XX-$XX:是传给编辑器脚本的自定义参数,可以由jenkins自动填写
2.通过jenkins来实现部署网页打包器,通过网页来调用上面的命令,一键自动打包apk包和资源ab包
【Unity】Jenkins自动打包入门小结_两水先木示的博客-CSDN博客_unity jenkins
3.assetbundle优化方式:
- 解决资源互相依赖:blueberryzzz/ReferenceFinder: 这是一个用来查找资源引用和依赖的插件,通过缓存来保存资源间的引用信息,通过树状结构直观的展示。 (github.com)
- 官方的ab包浏览器:Unity-Technologies/AssetBundles-Browser: Editor tool for viewing and debugging asset bundle contents before and after builds (github.com)
- 合理分包,有些资源需要零散,有些资源需要合起来打成一个包
- 如果打包时依赖到没有设置包名的资源,会直接将该资源拷贝到包里。每一个用到该资源的budle,都会拷贝一份,导致浪费了许多空间。所以必须为这个公用的资源设置包名,才能变成一份,其他包里只存它的引用。
注意:每次打包的时候,调用 BuildPipeline.BuildAssetBundles,会将当前所有已经设置了bundle名字的资源进行打包,名字相同的打成一个包,会查询引用,如果引用到的资源没设置bundle名字,则会为每个用到这个资源的bundle都拷贝一份进去。
多线程打包,查询资源互相依赖就变得尤其重要。避免将相同引用的资源,多次打进包里。比如有包a,b,c,a跟b都引用了c,用线程1打包a,线程2打包b,那么2个线程都会打包一份c。造成资源重复。
4.优化打包速度:
- 利用多进程打包,开启多个Unity进程,分别打同个项目的不同资源,前提是能做好资源归类,哪些资源是没有互相依赖的,可以分到一起,不同进程不能有互相依赖的包
- 利用多线程进行IO读取,主要耗时在AssetBundle的API调用上,将IO读取更改为并行处理。优化md5方法,减少内存复制导致的gc
- 默认进行增量式打包,只打变动过的资源,不打全包。(可以使用BuildAssetBundleOptions.ForceRebuildAssetBundle参数触发强制重新打包)
- 合理分包控制打包粒度,100个资源,打成一个bundle的速度要比打成100个独立的bundle的速度快很多。但若有某个资源修改过,打成一个budle的,需要整个包重新打,而独立包的,只会重新打变化过的。
- 分布式打包,将打包任务分配到不同的局域网机器内,分别进行不同的任务(理论上可用行,没实际验证过)
5.资源加载:参考:深入Assetbundle机制 · GameDev (gitbooks.io)
加载方式:
- Resource.Load:最古老的加载方式,资源需要放到Resource文件夹下跟程序一同打包,不考虑此方式
- File read + AssetBundle.CreateFromMemory + AssetBundle.Load:先通过加载文件到内存,再通过CreateFromMemory 将内存里的文件转成ab资源,因此需要消耗2倍的内存,而且一次性加载整个文件,但好处是可以加密文件
- AssetBundle.CreateFromFile + AssetBundle.Load:直接加载ab文件,最常用的方式,而且是按需加载的,不会一次性加载整个ab,ab头部有资源每个文件的偏移位置, AssetBundle.Load时按需加载ab中某部分文件
- 合理利用异步加载来优化程序卡顿,不要一次性大量地加载,释放资源。进行分帧处理
- 不要频繁地加载卸载ab:有引用时引用计数+1,没引用时-1,在引用计数为0时不要立刻删除,避免又有地方要马上加载造成重新加载一遍,增加一个释放计时器,超过一定时间没任何地方引用才真正释放。
Unity新版打包系统:关于Addressable的一些日常应用 - 知乎 (zhihu.com)
1.addressable的全部操作均为异步操作,不会阻塞主线程
2.提供了所有问题的解决方案,如资源的打包,加载,更新,依赖项,性能分析等
3.addressable则可以在不打包的情况下在Editor里模拟打包状态进行测试
第三方的开源资源加载方案:xasset
xasset 的资源加载策略是:
-
查询缓存中是否有记录,如果有直接取缓存的地址。
-
缓存中如果没有,先看安装包内部是否有,如果有直接返回包内的加载地址。
-
如果包内没有,再看下载目录是否有,如果有直接返回下载目录的地址。
-
下载目录没有,直接返回服务器的下载地址。
打包到移动平台的坑:
2.在移动平台烘培的光照贴图会丢失,要把Project Settings -> Graphics -> Lightmap Modes 改为 Custom,并且把Baked Non-Dirceiontal打开,重新打包出来的就正常了