• Unity减少发布打包文件的体积(二)——设置WebGL发布时每张图片的压缩方式


    一个项目在发布成WebGL后,其体积至关重要,体积太大,用户加载会经历一个漫长的等待…轻则骂娘,重则用脚把电脑踢烂(扣)…

    那么如何减少发布后的体积呢,本文从图片的压缩开始入手。

    前传回顾:
    Unity减少发布打包文件的体积(一)——获取精灵图片的信息限制它的大小

    一、徒手设置每张图片的压缩方法

    在assets文件夹里选中一个Image,在Inspector底部有一个各发布平台的压缩设置,如下图中4的部分。
    在此处设置压缩格式时,只针对发布时进行压缩,不会修改工程资源的原始文件,这样如果你发布成exe时,可以用高清的设置(而如果直接改了原始图片,则发布成exe时,画质被降低)。
    在这里插入图片描述

    1、压缩格式Format的说明(来源Claude.ai):

    • ASTC (Adaptive Scalable Texture Compression): 这是一个非常灵活的纹理压缩格式,可以提供一系列不同的压缩比,以适应各种不同的应用需求。ASTC由ARM开发,旨在为各种不同的2D和3D内容提供优质的可压缩性能。它被广泛用于移动设备,特别是那些使用ARM集成电路的设备。

    • ETC (Ericsson Texture Compression): ETC是一种开放的、有损的纹理压缩格式,使用在OpenGL和OpenGL ES。ETC1版本不支持alpha通道,而ETC2支持alpha通道。由于其广泛的设备支持和合理的压缩效果,ETC被广泛应用于移动设备。

    • DXT (DirectXTex): 也被称为S3TC,这是一种有损的纹理压缩格式,主要应用在DirectX场景。DXT格式为纹理提供5:1的压缩比率且支持alpha通道,对于PC和一些游戏主机上的3D应用,通常采用DXT格式。

    • BC (Block Compression): BC是一系列DirectX的一部分提供的纹理压缩方法,这其中包括DXT。BC系列(包括BC1-BC7)是几种特殊用途的格式,它们在纹理分辨率、细节和压缩比率上提供多种选择,但并非所有设备都支持。

    • EAC (Ericsson Alpha Compression): 这是ETC2压缩方法的一部分,用于对alpha通道进行压缩。EAC提供了更好的颜色和alpha通道保真度,特别适合那些需要用到透明效果的游戏或者带有alpha混合的特效。

    2、MaxSize的计算

    Unity中如果你不单独设置,它的默认值大概就是2048,你可以写一个函数,根据分辨力来计算maxSize的值。
    在这里插入图片描述

    /// 
    /// 获取图片的分辨率,取分辨率中高宽的最大值,然后返回图片的【MaxSize】
    /// MaxSize的定义:assets->Image->【Texture2D ImportSettings】->【Override For WebGL】->【Max Size】 
    /// 区间:16,32,64,128,256,512,1024,2048,4096,8192,16384
    ///
    /// 举例:图片分辨率 = 12 * 24,那么图片的MaxSize = 32
    /// 
    /// 
    /// 
    public static int GetMaxSize(Texture2D texture)
    {
       //分辨率区间的预备
       var start = new List<int> { 0, 16, 32, 64, 128, 256, 512, 1024, 2048, 4096, 8192, 16384 };
       var end = new List<int> { 16, 32, 64, 128, 256, 512, 1024, 2048, 4096, 8192, 16384, 100000 };
       var zones = start.Zip(end, (item1, item2) => (startIdx: item1, endIdx: item2)).ToList();
    
       //取分辨率高宽的最大值
       var size = new List<int> { texture.width, texture.height }.Max();  //取【宽】【高】中的最大值
    
       //判断所属的区间
       var maxSize = zones.First(x => x.startIdx <= size && size <= x.endIdx).endIdx;
       //Debug.Log($"图的分辨率 = {texture.width} * {texture.height} size = {size}, MaxSize = {maxSize}");
       return maxSize;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24

    3、 Format的设置:

    Unity面板上提供的各种压缩算法:
    在这里插入图片描述
    自己亲自指挥亲自部署时,代码中可选的压缩格式:
    在这里插入图片描述

    4、提问:所有的图片能不能一键设置呢?

    可以的,你可以自己写一个编辑器脚本(俗称插件),也可以让AI帮你写一个…然后自己慢慢改

    二、一键设置所有图片的Build时的压缩选项

    1、快捷菜单入口

    右键全选图片 -> 【设置发布WebGL时贴图的压缩格式】
    在这里插入图片描述

    处理中…
    在这里插入图片描述
    在这里插入图片描述

    2、压缩效果

    压缩结束后,发现包的大小从230M减少到138兆。

    3、实现的基本思路

    • (1)找到所有的全选物体
    Object[] textures = Selection.GetFiltered(typeof(Texture2D), SelectionMode.DeepAssets);
    
    • 1
    • (2)单个物体的压缩选项设定

        创建特定平台压缩实例
        勾选压缩
        设置参数
        Apply
      
      • 1
      • 2
      • 3
      • 4
    // 创建特定平台压缩实例
    TextureImporterPlatformSettings platformSettings = new TextureImporterPlatformSettings();
    platformSettings.overridden = true;
    platformSettings.name = "WebGL";
    
    // 设置为压缩
    platformSettings.textureCompression = TextureImporterCompression.Compressed;
    
    // 设置压缩格式
    platformSettings.format = format;                                     //TextureImporterFormat.ASTC_12x12;
    platformSettings.compressionQuality = compressionQuality;             //40
    platformSettings.maxTextureSize = GetMaxSize(texture as Texture2D);   //32
    
    //设置importSettings
    TextureImporter importer = AssetImporter.GetAtPath(AssetDatabase.GetAssetPath(texture)) as TextureImporter;
    importer.SetPlatformTextureSettings(platformSettings);
    
    //Apply 设置
    importer.SetPlatformTextureSettings(platformSettings);
    
    //保存资源
    importer.SaveAndReimport();
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22

    三、附录(代码)

    运行方式,放到任何Editor文件里

    using System.Collections.Generic;
    using System.Linq;
    using UnityEngine;
    using UnityEditor;
    
    public class SetTextureCompression
    {
        //****************************************参数设置区**********begin
        //TODO 做成EditWindow类型
    
        private static TextureImporterFormat format = TextureImporterFormat.ASTC_12x12;  //图片压缩格式
        private static int compressionQuality = 60;                                      //压缩比例
        private static string platform = "WebGL";                                        //发布的平台 
    
        //************************************************************end
    
        /// 
        /// 设置贴图在build时的压缩选项
        /// 
        [MenuItem("Assets/设置发布WebGL时贴图的压缩格式")]
        static void SetCompression()
        {
            int count = 0;
    
            Object[] textures = Selection.GetFiltered(typeof(Texture2D), SelectionMode.DeepAssets);
            if (textures.Length > 0)
            {
                foreach (Object texture in textures)
                {
                    // 创建特定平台压缩实例
                    TextureImporterPlatformSettings platformSettings = new TextureImporterPlatformSettings();
                    platformSettings.overridden = true;
                    platformSettings.name = platform;
    
                    // 设置为压缩
                    platformSettings.textureCompression = TextureImporterCompression.Compressed;
    
                    // 设置压缩格式
                    platformSettings.format = format;                                     //TextureImporterFormat.ASTC_12x12;
                    platformSettings.compressionQuality = compressionQuality;             //40
                    platformSettings.maxTextureSize = GetMaxSize(texture as Texture2D);   //32
    
                    //设置importSettings
                    TextureImporter importer = AssetImporter.GetAtPath(AssetDatabase.GetAssetPath(texture)) as TextureImporter;
                    importer.SetPlatformTextureSettings(platformSettings);
    
                    //Apply 设置
                    importer.SetPlatformTextureSettings(platformSettings);
    
                    //保存资源
                    importer.SaveAndReimport();
    
                    count++;
                }
                //Debug.Log("Texture Compression Set!");
            }
            else
            {
                Debug.LogWarning("没有选中图片!");
            }
            Debug.Log($"一共处理了{count}张图片!");
        }
    
        /// 
        /// 获取图片的分辨率,取分辨率中高宽的最大值,然后返回图片的【MaxSize】
        /// MaxSize的定义:assets->Image->【Texture2D ImportSettings】->【Override For WebGL】->【Max Size】 
        /// 区间:16,32,64,128,256,512,1024,2048,4096,8192,16384
        ///
        /// 举例:图片分辨率 = 12 * 24,那么图片的MaxSize = 32
        /// 
        /// 
        /// 
        static int GetMaxSize(Texture2D texture)
        {
            //分辨率区间的预备
            var start = new List<int> { 0, 16, 32, 64, 128, 256, 512, 1024, 2048, 4096, 8192, 16384 };
            var end = new List<int> { 16, 32, 64, 128, 256, 512, 1024, 2048, 4096, 8192, 16384, 100000 };
            var zones = start.Zip(end, (item1, item2) => (startIdx: item1, endIdx: item2)).ToList();
    
            //取分辨率高宽的最大值
            var size = new List<int> { texture.width, texture.height }.Max();  //取【宽】【高】中的最大值
    
            //判断所属的区间
            var maxSize = zones
                .First(x => x.startIdx <= size && size <= x.endIdx)
                .endIdx;
            //Debug.Log($"图的分辨率 = {texture.width} * {texture.height} size = {size}, MaxSize = {maxSize}");
            return maxSize;
        }
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
  • 相关阅读:
    接口测试概念
    Pointnet++改进卷积系列:全网首发RFAConv创新空间注意力和标准卷积运算 |即插即用,提升特征提取模块性能
    prometheus:(二)监控概述(你永远逃不出我的手掌哈哈)
    MySQL数据库之主从复制及读写分离
    Fuzz测试 发现软件中的隐患和漏洞的秘密武器
    Sonar: static 修饰符顺序违法了JLS建议
    PySnooper – 永远不要使用print进行调试
    物联网感知-光纤光栅传感器技术
    三维控件中定位一个点_vtkPointWidget
    师哥带你每天三道蓝桥杯题[冲刺省一]~建议收藏
  • 原文地址:https://blog.csdn.net/dzj2021/article/details/134455970