Skip to content

Unity3D 资源打包吐槽

Unity3D 资源打包吐槽 published on Unity3D 资源打包吐槽有84条评论

unity47

Unity3D的资源打包以及它的加载机制真的是一个坑,非常的XX(粗鲁了!-_-)。

先回顾下传统PC网络游戏的资源打包。

一般各个游戏开发厂商会自己定义一种资源包格式,然后将资源分门别类的放到这个大的资源包文件中,文件中可以在头部包含一个列表文件,表示什么资源在什么位置、资源的大小、资源的唯一标示等。也有的游戏转门维护一个资源列表文件,让它和打包文件分开,这样的好处是可以独立升级资源。例如:某个模型变了,只需要将这个模型通过网络方式下载到本地,添加或合并到一个最优先加载的资源打包文件中。游戏启动后,先加载优先级最高的资源打包文件的资源列表,再加载老旧的资源打包文件的资源列表,如果新旧资源列表都有同一个资源,那当然以最新的为准,同时打开所有的资源打包文件,得到文件句柄,注意这里仅仅是打开文件得到一个操作句柄,并不占用内存,换句话说没有把整个打包文件加载到内存中,等程序需要某个资源的时候,根据资源的名字或是唯一标识,通过之前获得的文件句柄直接移动文件指针到对应的文件位置去取资源,然后才加载进内存。在打包过程中,不会存在什么依赖不依赖的关系,都是单独的将每一个资源压缩,然后放在相应的位置,一切都是写代码控制,虽然麻烦,但是没有坑,机制一旦建立好,用起来非常简单,运行期也是要什么加载什么,不用了就释放,再清晰不过了。但是,到了Unity3D中,这一切都不一样了。

我们来看Unity3D的资源打包……(忍住不说脏话)

啪,首先给你来个概念,依赖关系。意思就是你打包的时候,要考虑依赖关系,举个例子,一个建筑,那就有模型、贴图、材质什么的,这些就叫这个建筑的依赖文件,打包的时候可以把这个建筑做成一个预制体来打包,如果不考虑依赖关系,打包出来的预制里面就带模型、贴图、材质了,你使用的时候直接实例化这个预制就可以用了,你是不是感觉很爽?别急马上你就不爽了。如果还有另一个建筑也用到了相同的贴图和材质,你又把他做成预制体,然后又打包,实例化后也可以正常使用,这里开始坑就出现了,你的2个打包文件中,把同一个材质打包了2次!当同时你加载这两个建筑的时候,Unity3D,会把这两个AssetBundle文件都加载,自然的相同的贴图、材质这些也就加载了两次,其实这还算好,毕竟加载完AssetBundle完成,你要实例化这个预制,实例化完成后就可以释放AssetBundle文件占用的内存了,但是就在你实例化两个建筑的时候,更深的坑接着出现了!这个相同的贴图和材质,有2份相同的拷贝。只要游戏中存在这两中预制类型的建筑(实例可能无数个),就始终会存在两份相同的贴图、材质的拷贝,如果你使用完AssetBundle不立即释放,那么就是四份相同的拷贝,这绝对是天坑吧。

其实人家Unity3D也考虑到了,所以刚才就告诉你了,咋们可以依赖关系打包啊,你为啥不用?OK,接着刚才的2建筑我们用依赖关系来打包…(省略几行代码)……OK打包完成,现在2个预制打包到一个AssetBundle里面了,加载看看,嗯,只有一份贴图和材质的实例,这一个AssetBundle也别刚才那两个合起来的大小要小,不错不错,节约了内存,好高兴啊。别高兴的太早,坑来了,我发现我的一个建筑在模型上有点瑕疵,要更新一下,肿么办,能单独更新这个模型么?对不起,不行!!!问题放大一点,几十个建筑,都依赖了相同的贴图和材质,当然也有各自专用的贴图和材质,我都是这样打包的,我只有一个AssetBundle,算小点吧,20MB,你要我更新整个AssetBundle,这不是害人么?PC上估计还好点,手机上的话,很多有性格、有个性的用户立马不爽了,槽,昨天还好好的,今天一开游戏就要用老子20MB的流量,哥不耍了还不行么!!

Unity3D又说了,你傻啊,你先push那个什么依赖关系把公共贴图和材质各自打包,然后再打包那个建筑文件,最后pop那个什么依赖关系,这样建筑文件里的AssetBundle里就不包含那个公共的贴图和材质了,你试试看?好吧,我试试。还是刚才那个例子,这样两个建筑打包出来就4个AssetBundle了,贴图一个,材质一个,2建筑模型各一个。好了,来跑程序吧,咦,怎么是个白的建筑?Unity3D又说了,你要先加载你的贴图AssetBundle,再加载你的材质AssetBundle,最后才能加载建筑那个AssetBundle。我槽,这又是一坑吧。我的共享纹理不止一个,有几个咋办,有几十个咋办?

敢不敢提供 一个通用一点的机制啊?要么你就不要提供这种半残的机制,完全让我们自己可以控制打包文件的格式以及内容啊!

吐槽总结:

  1. AssetBundle内存控制不友好,我还没读内容就先要把这个加载到内存
  2. AssetBundle用单一文件打包相关内容,使用非常方便,但是项目越大越耗费的内存越多
  3. AssetBundle用单一文件打包相关内容,打包的内容越多,更新量越大(整个包都要更新)
  4. AssetBundle用多文件依赖方式打包单个资源,使用起来非常复杂,手动写一个个的载入根本不现实,要自己实现一套AssetBundle和Asset的管理机制才行。

纯属个人吐槽,不喜勿喷

原创文章,转载请注明: 转载自游戏无界·达秀的黑暗空间

本文链接地址: Unity3D 资源打包吐槽

本站作品除特殊申明外均为原创,采用知识共享署名-非商业性使用-禁止演绎 3.0 Unported许可协议进行许可。如果需转载请保持文章完整性和标明原文出处,禁止商业用途。

  1. Pingback: terrance

  2. Pingback: Gordon

  3. Pingback: Dana