因为一个疏忽差点被老板开除,Unity解决包体过大的问题记录

Posted 陈言必行

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了因为一个疏忽差点被老板开除,Unity解决包体过大的问题记录相关的知识,希望对你有一定的参考价值。

一,发现问题:

最近在做一个类似于《保卫萝卜》这种每个关卡需要更换一个背景地图的游戏,大概做了六十关。也就是说有六十张比较大的背景图在工程中。

包体大小:

  • ios下打包ipa大小200M。
  • 在Windows下打包apk大小170M。

查看打包日志:

构建报告

打开方式: … --> Open Editor Log --> 搜索“Build Report”
打开方式

由上面日志可以看出,包体主要大小占用为:Textures 214.7M 占用包的91.5%;

查看工程中所有贴图所在文件夹大小,一共不到40M。
按照上面资源占比查看第一个图在Unity工程中的大小确实是8.4M,而在文件夹中看却只有340KB。

锁定问题:在Unity中的图片大小和在文件夹中的图片大小不一致。


二,分析问题:

为什么在文件夹中显示为几百kb的图片,到Unity工程中变为几兆?

经过各种折腾,最终确定是因为图片尺寸和在工程中设置的格式导致的。

先看结论:

  • 贴图导入unity后会自动设置成压缩格式,它会先判断贴图是否有透明通道。
  • android:不带透明通道压缩成ETC1,带透明通道压缩成ETC2,不被4整除的回退到RGBA32
  • IOS: 不带透明通道压缩成RGB PVRTC,带透明通道压缩成RGBA PVRTC ,不是2的整数次幂回退到RGBA32

Texture图片拖入的时候,如下图所示; unity会默认设置ToNerest,这样会自动保证Android平台下图片被4整除,IOS平台下图片是2的整除次幂,所以默认情况下图片都可以得到最好的压缩。

图片格式


三,解决问题

游戏背景图使用的是Sprite做的,所以贴图类型使用的是:Sprite(2D and UI),如下图:此时贴图大小就是2.6M。

示例1

而类型是Default 并勾选ToNearest时,大小就和在文件夹中的图片大小差不多了,都是300多KB:

示例2


细心的你应该发现了,当Texture Type 选择 Sprite(2D and UI) 时,下面会有行类似下面这样的警告:

Android:

Only textures with wideth/height being multiple of 4 can be compressed to DXT1 format
只有宽度/高度为4倍的纹理才可以压缩为DXT1格式

IOS:

Only POT textures can be compressed to PVRTC format
只有POT纹理可以压缩到PVRTC格式

其实当时要不是全部选中批量修改的话,估计也会注意到这个警告,并且能看到文件大小问题;这样就不会等到打包的时候,再回头来推是什么原因导致包体变大了。【还是不够细心啊…】


解决方案:

使用 3D物体+材质球 的方式替换 Sprite 做为背景,这样就不用改变Texture类型了。

修改后

  • ipa从近200M降到了87.7M

ipa大小

  • Apk从169M降到了65.1M
    apk大小对比

四,相关知识:

4.1纹理导入:

  • Unity 支持读取以下文件格式
    BMP,EXR,GIF,HDR,IFF,JPG,PICT,PNG,PSD,TGA,TIFF
    Unity 可导入多层PSD文件,导入时自动展平,但图层在资源本身中维护。

  • 纹理尺寸大小
    理想情况下,纹理尺寸大小应该是每边为2的整数次幂(如:2,4,8,16像素(px)等等)。

    Unity 允许使用NOPT(非2的幂)纹理大小;但是,NPOT纹理大小通常需要多一点内存【我遇到的问题】,并且GPU的采样速度可能更慢。因此,我们尽量让美术出的图使用2的幂大小,以便于提高性能节省内存。

    如果平台或GPU不支持NPOT纹理带下,Unity会对纹理进行缩放和填充已达到下一个2的幂的大小。

    纹理导入后可将Advanced选项选择Not Power of 2,在导入时放大NPOT纹理资源

纹理导入

4.2纹理类型:

以下是纹理检视面板 (Texture Inspector) 窗口中可用于在 Unity 中配置各种纹理类型的属性

类型名称解释说明
DefaultDefault 是用于所有纹理的最常用设置。此选项可用于访问大多数导入纹理的属性。
Normal MapNormal map 是可将颜色通道转换为适合实时法线贴图的格式。
Editor GUI and Legacy当我们要在 HUD 或 GUI 控件上使用纹理,选择此项。
Sprite (2D and UI)当我们要在2D游戏中或者作为UI使用时,选择此项使用此纹理作为精灵。
CursorCursor 是用于将纹理用作自定义游标的格式。
Cookie当我们需要场景光源的剪影时,选择此项。
LightmapLightmap 是要将纹理用作光照贴图的格式。
Single Channel当我们需要纹理单通道时,选择此项。

4.3特定于平台的覆盖的纹理压缩格式

虽然Unity支持上面4.1说的很多种图像格式作为导入纹理的源文件,但在各种平台和设备上都会进行专门格式压缩,这些格式针对快速纹理才有进行了优化,进而各个平台也有自己不同的专有格式。

默认情况下,Unity编辑器会自动将纹理转为核实的格式,已匹配你当前选择平台。大多数平台上,可选择许多不同的受支持的纹理压缩格式。Unity为每个平台设置了一些默认格式,但在某些情况下,我么可能希望覆盖默认值并为某些纹理想选择不同的压缩格式。

要为每个平台应用自定义设置,可是在贴图的导入配置上,选择特定于平台的覆盖 (Platform --> specific overrides)面板覆盖特定平台的默认设置。如下图:覆盖IOS平台

选择平台

所有支持的纹理压缩格式

下表显示了每个平台上可用的纹理压缩格式选项以及生成的压缩文件大小(基于 256 像素平方图像)。选择纹理压缩格式需要在文件大小和质量之间取得平衡;质量越高,文件越大。在下面的描述中,假定游戏纹理的最终文件大小为 256 x 256 像素。

纹理压缩格式描述大小(256x256 像素纹理)平台支持
RGB Compressed DXT1压缩无符号标准化整数 RGB 纹理。32KB(4 位/像素)Windows、Linux、macOS、PS4、XBox One、Android(Nvidia Tegra 和 Intel Bay Trail)、WebGL。
RGB Crunched DXT1与 RGB Compressed DXT1 类似,但使用 Crunch 压缩方式进行压缩。有关 Crunch 压缩的更多信息,请参阅上面的注意事项。可变,取决于纹理中内容的复杂程度。Windows、Linux、macOS、PS4、XBox One、Android(Nvidia Tegra 和 Intel Bay Trail)、WebGL。
RGBA Compressed DXT5压缩无符号标准化整数 RGBA 纹理。8 位/像素。 64KB(8 位/像素)Windows、Linux、macOS、PS4、XBox One、Android(Nvidia Tegra 和 Intel Bay Trail)、WebGL。
RGBA Crunched DXT5与 RGBA Compressed DXT5 类似,但使用 Crunch 压缩方式进行压缩。有关 Crunch 压缩的更多信息,请参阅上面的注意事项。可变,取决于纹理中内容的复杂程度。Windows、Linux、macOS、PS4、XBox One、Android(Nvidia Tegra 和 Intel Bay Trail)、WebGL。
RGB Compressed BC6H压缩无符号浮点/高动态范围 (HDR) RGB 纹理。64KB(8 位/像素)Windows Direct3D 11:OpenGL 4、Linux。
RGB(A) Compressed BC7高质量压缩无符号标准化整数 RGB 或 RGBA 纹理。64KB(8 位/像素)Windows Direct3D 11:OpenGL 4、Linux
RGB Compressed ETC压缩 RGB 纹理。这是适用于 Android 项目的不带 Alpha 通道的纹理的默认纹理压缩格式。32KB(4 位/像素)Android、iOS、tvOS。
RGB Crunched ETC与 RGB Compressed ETC 类似,但使用 Crunch 压缩方式进行压缩。有关 Crunch 压缩的更多信息,请参阅上面的注意事项。可变,取决于纹理中内容的复杂程度。Android、iOS、tvOS。
RGB Compressed ETC2压缩 RGB 纹理。32KB(4 位/像素)Android (OpenGL ES 3.0)
RGBA Compressed ETC2压缩 RGBA 纹理。这是适用于 Android 项目的带有 Alpha 通道的纹理的默认纹理压缩格式。64KB(8 位/像素)Android (OpenGL ES 3.0)、iOS (OpenGL ES 3.0)、tvOS (OpenGL ES 3.0)
RGBA Crunched ETC2与 RGBA Compressed ETC2 类似,但使用 Crunch 压缩方式进行压缩。有关 Crunch 压缩的更多信息,请参阅上面的注意事项。可变,取决于纹理中内容的复杂程度。Android (OpenGL ES 3.0)、iOS (OpenGL ES 3.0)、tvOS (OpenGL ES 3.0)
RGB Compressed PVRTC 2 位高压缩 RGB 纹理。质量低,但较小,因此提高了性能。16KB(2 位/像素)Android (PowerVR)、iOS、tvOS。
RGBA Compressed PVRTC 2 位高压缩 RGBA 纹理。质量低,但较小,因此提高了性能。16KB(2 位/像素)Android (PowerVR)、iOS、tvOS。
RGB Compressed PVRTC 4 位压缩 RGB 纹理。高质量纹理,尤其是颜色数据,但可能需要很长时间压缩。32KB(4 位/像素)Android (PowerVR)、iOS、tvOS。
RGBA Compressed PVRTC 4 位压缩 RGB 纹理。高质量纹理,尤其是颜色数据,但可能需要很长时间压缩。32KB(4 位/像素)Android (PowerVR)、iOS、tvOS。
RGB Compressed ATC压缩 RGB 纹理。32KB(4 位/像素)Android (Qualcomm - Adreno)、iOS、tvOS。
RGBA Compressed ATC压缩 RGBA 纹理。64KB(8 位/像素)Android (Qualcomm - Adreno)、iOS、tvOS。
RGB 16 位65,000 种颜色,没有 Alpha。使用比压缩格式更多的内存,但可能更适合没有渐变的 UI 或清晰纹理。128KB(16 位/像素)所有平台。
RGB 24 位真实色彩,但没有 Alpha。192KB(24 位/像素)所有平台
Alpha 8高质量 Alpha 通道,但没有任何颜色。64KB(8 位/像素)所有平台。
RGBA 16 位低质量真实色彩。这是具有 Alpha 通道的纹理的默认压缩格式。128KB(16 位/像素)所有平台。
RGBA 32 位真实色彩,并有 Alpha。这是具有 Alpha 通道的纹理的最高质量压缩格式。256KB(32 位/像素)所有平台。

PS:关于 Android 的注意事项

  • 一般情况下,ETC2 压缩是 Android 最高效的选项,可提供最佳的质量与文件大小平衡。
  • 要在纹理中存储 Alpha 通道,请使用 RGBA16 位压缩,这是所有硬件供应商都支持的格式。

以上是关于因为一个疏忽差点被老板开除,Unity解决包体过大的问题记录的主要内容,如果未能解决你的问题,请参考以下文章

我在公司项目上用了微前端,差点被开除

差点被开除:一次订单号重复的事故

自如首创 iOS 图片资源极致优化方案

在项目中随手把haseMap改成了currenHaseMap差点被公司给开除了

在项目中随手把haseMap改成了currenHaseMap差点被公司给开除了

差点被开除,只因用mysql的limit做分页