Unity隐藏的资源引用坑

由于发现项目在运行的时候资源占用内存比较高,特别是某些特效出现时,内存会一下升高很多,于是针对某些特效资源做了检查,发现了一个比较令人吃惊的问题。
Unity隐藏的资源引用坑_第1张图片
第一个问题,在这个特效里面,其实完全没有用到这个材质球的,而且材质球上面引用了3张特别大的贴图,包括了法线贴图和高光贴图。注意,这个特效里面是完全没有看到这些效果的。
Unity隐藏的资源引用坑_第2张图片
第二个问题,特效完全不是这个形状的,但却引用了这个fbx模型,顺便fbx引用了一个带法线贴图的材质球,所以引用了一些贴图。注意,这个特效里面完全没有出现过这个模型。

于是开始检查问题。先从第一个问题检查起。
Unity隐藏的资源引用坑_第3张图片
咨询了特效师,原来他已经重新建了一个新的材质球给特效里面的相同模型用,那么现在出问题的材质球,实际上是fbx自己引用的。由于在fbx导入的时候勾选了Import Material,所以fbx会依赖一个我们可以操作的材质球。(如果不勾,会存在另外一个问题,这个问题以后有时间再写文章说明了,这次先不说。)
于是我打算把那个fbx引用的其实没有用的材质球里面的其他通道去掉。我直接把之前复杂的shader改成了简单的Unlit/Texture
Unity隐藏的资源引用坑_第4张图片
结果发现,那些没有显示在材质球的通道列表里面的贴图,仍然被材质球引用着。

这里先说笨的解决办法,后面有直接批量修改文件的解决办法。
笨的解决办法,其实就是把材质的shader换回之前的复杂shader,然后把不要的通道去掉。最后再换回简单的shader
Unity隐藏的资源引用坑_第5张图片
好了,这次去掉了通道上的图片,再检查依赖,之前引用的图片都没有了。
想想是不是很可怕?你以为没有用的贴图,居然unity会帮你偷偷的保存下来了。这导致的问题是什么?由于引用关系,你虽然没有实际用到这些贴图,但打包AssetBundle的时候,会包含这些资源一起打包出去了。

然后看第二个问题,为什么一个没有出现过的模型,会被特效依赖。实际上有了第一个问题的经验后,我也很容易猜到原因了。
Unity隐藏的资源引用坑_第6张图片
虽然现在看来,粒子里面的Shape和Renderer里面都没有用到Mesh选项,但是,实际上咨询了特效师,他做这个特效的时候,是直接从别的特效预设复制过来然后做修改的,原始的那个特效粒子,Shape是用了Mesh的,而Mesh就是那个莫名其妙出现的fbx。
Unity隐藏的资源引用坑_第7张图片

同样先说笨方法,只要把类型换回mesh,看到了引用,然后把mesh里面引用的fbx去掉就行了,依赖就不存在了,连带fbx依赖的那些材质球和贴图都没有了。
Unity隐藏的资源引用坑_第8张图片

下面来说说聪明的解决办法吧:
先说材质球引用多余贴图的问题,打开材质的mat文件,可以看到,导致一直引用的原因,是mat文件里面本身就是按照shader参数的名称,存储了对应通道的fileId和guid。如下图,虽然Unlit/Texture的shader只用到了_MainTex,但_BumMap、_Speculer和_Matcap里面还是存在着贴图的引用的。
Unity隐藏的资源引用坑_第9张图片
Unity隐藏的资源引用坑_第10张图片
知道了之后,接下来就比较简单了,做一个工具,指定一个文件夹查找范围,然后获取文件夹里面所有的mat文件,逐个打开,先通过里面m_Shader字段里面的guid,加载到对应的shader文件,然后查找shader实际有多少个有用的贴图通道的变量名, 然后把当前mat文件所有的贴图通道做一个对比,哪一些是shader没有用到的却有引用贴图的,把它干掉就行了。

粒子特效同理,打开prefab文件,可以看到粒子里面有个ShapeModule的模块信息,里面有个type,还有个m_Mesh的信息。实际上,type等于6才可能是mesh类型的,如果不等于6,而m_Mesh又有引用内容,肯定就是有问题了,同样的把它干掉就行了。
Unity隐藏的资源引用坑_第11张图片

我不知道Unity这样设计的目的是什么,但如果用户不知道这个问题,特别是制作美术资源的美工们,很习惯各种复制资源做修改当做新资源使用的。这样的情况下,究竟你的项目里面有多少这样莫名其妙的无谓引用?赶紧查一下吧。

你可能感兴趣的:(unity相关)