三国卡牌客户端基础资源仓库
yyl
2026-03-28 25eb0e50d4e815efb16d1a9953beac6ea1c7cfc3
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
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
using UnityEditor;
using UnityEditor.U2D;
using UnityEngine;
using System.Collections.Generic;
 
/// <summary>
/// 批量将所有贴图和图集的 WebGL 平台格式改为 ETC2 压缩。
/// 根据原始格式自动判断是否需要 Alpha 通道:
///   - 有 Alpha → ETC2_RGBA8
///   - 无 Alpha → ETC2_RGB4
/// 
/// 使用菜单:程序/Sprite/WebGL贴图转ETC2
/// </summary>
public class ConvertWebGLTextureToETC2
{
    [MenuItem("程序/Sprite/WebGL贴图转ETC2(全部)")]
    public static void ConvertAll()
    {
        ConvertTextures();
        ConvertSpriteAtlases();
 
        AssetDatabase.SaveAssets();
        AssetDatabase.Refresh();
    }
 
    [MenuItem("程序/Sprite/WebGL贴图转ETC2(仅贴图)")]
    public static void ConvertTexturesOnly()
    {
        ConvertTextures();
        AssetDatabase.SaveAssets();
        AssetDatabase.Refresh();
    }
 
    [MenuItem("程序/Sprite/WebGL贴图转ETC2(仅图集)")]
    public static void ConvertAtlasesOnly()
    {
        ConvertSpriteAtlases();
        AssetDatabase.SaveAssets();
        AssetDatabase.Refresh();
    }
 
    static void ConvertTextures()
    {
        var guids = AssetDatabase.FindAssets("t:Texture2D", new[] { "Assets/ResourcesOut" });
        int total = guids.Length;
        int converted = 0;
        int skipped = 0;
 
        for (int i = 0; i < total; i++)
        {
            var assetPath = AssetDatabase.GUIDToAssetPath(guids[i]);
            EditorUtility.DisplayProgressBar("WebGL贴图转ETC2", $"[{i + 1}/{total}] {assetPath}", (float)i / total);
 
            var importer = AssetImporter.GetAtPath(assetPath) as TextureImporter;
            if (importer == null)
            {
                skipped++;
                continue;
            }
 
            bool needsAlpha = NeedsAlpha(importer);
            var targetFormat = needsAlpha ? TextureImporterFormat.ETC2_RGBA8 : TextureImporterFormat.ETC2_RGB4;
 
            var webGLSettings = importer.GetPlatformTextureSettings("WebGL");
 
            // 已经是目标格式则跳过
            if (webGLSettings.overridden && webGLSettings.format == targetFormat)
            {
                skipped++;
                continue;
            }
 
            webGLSettings.overridden = true;
            webGLSettings.maxTextureSize = GetMaxTextureSize(importer);
            webGLSettings.textureCompression = TextureImporterCompression.Compressed;
            webGLSettings.format = targetFormat;
            webGLSettings.compressionQuality = 50;
 
            importer.SetPlatformTextureSettings(webGLSettings);
            importer.SaveAndReimport();
            converted++;
 
            Debug.Log($"[ETC2] 贴图 {(needsAlpha ? "RGBA8" : "RGB4")}: {assetPath}");
        }
 
        EditorUtility.ClearProgressBar();
        Debug.Log($"[ETC2] 贴图处理完成:转换 {converted},跳过 {skipped},共 {total}");
        EditorUtility.DisplayDialog("贴图转换完成",
            $"转换 {converted} 个,跳过 {skipped} 个,共 {total} 个贴图。",
            "OK");
    }
 
    static void ConvertSpriteAtlases()
    {
        var guids = AssetDatabase.FindAssets("t:SpriteAtlas", new[] { "Assets/ResourcesOut" });
        int total = guids.Length;
        int converted = 0;
        int skipped = 0;
 
        for (int i = 0; i < total; i++)
        {
            var assetPath = AssetDatabase.GUIDToAssetPath(guids[i]);
            EditorUtility.DisplayProgressBar("WebGL图集转ETC2", $"[{i + 1}/{total}] {assetPath}", (float)i / total);
 
            try
            {
                var importer = SpriteAtlasImporter.GetAtPath(assetPath) as SpriteAtlasImporter;
                if (importer == null)
                {
                    skipped++;
                    continue;
                }
 
                var webGLSettings = importer.GetPlatformSettings("WebGL");
 
                // 判断 Alpha:检查其他平台的设置来推断
                bool needsAlpha = AtlasNeedsAlpha(importer);
                var targetFormat = needsAlpha ? TextureImporterFormat.ETC2_RGBA8 : TextureImporterFormat.ETC2_RGB4;
 
                if (webGLSettings.overridden && webGLSettings.format == targetFormat)
                {
                    skipped++;
                    continue;
                }
 
                webGLSettings.overridden = true;
                webGLSettings.maxTextureSize = 2048;
                webGLSettings.textureCompression = TextureImporterCompression.Compressed;
                webGLSettings.format = targetFormat;
                webGLSettings.compressionQuality = 50;
 
                importer.SetPlatformSettings(webGLSettings);
                importer.SaveAndReimport();
                converted++;
 
                Debug.Log($"[ETC2] 图集 {(needsAlpha ? "RGBA8" : "RGB4")}: {assetPath}");
            }
            catch (System.Exception ex)
            {
                Debug.LogError($"[ETC2] 图集处理失败 {assetPath}: {ex.Message}");
            }
        }
 
        EditorUtility.ClearProgressBar();
        Debug.Log($"[ETC2] 图集处理完成:转换 {converted},跳过 {skipped},共 {total}");
        EditorUtility.DisplayDialog("图集转换完成",
            $"转换 {converted} 个,跳过 {skipped} 个,共 {total} 个图集。",
            "OK");
    }
 
    /// <summary>
    /// 判断贴图是否需要 Alpha 通道
    /// </summary>
    static bool NeedsAlpha(TextureImporter importer)
    {
        // 1. 检查贴图本身是否含 Alpha
        if (importer.DoesSourceTextureHaveAlpha())
            return true;
 
        // 2. 检查已有平台设置的格式来推断
        foreach (var platform in new[] { "Android", "iPhone", "Standalone" })
        {
            var settings = importer.GetPlatformTextureSettings(platform);
            if (settings.overridden && IsAlphaFormat(settings.format))
                return true;
        }
 
        // 3. 检查 alphaSource 设置
        if (importer.alphaSource != TextureImporterAlphaSource.None)
            return importer.DoesSourceTextureHaveAlpha();
 
        return false;
    }
 
    /// <summary>
    /// 判断图集是否需要 Alpha(通过检查其他平台的格式推断)
    /// </summary>
    static bool AtlasNeedsAlpha(SpriteAtlasImporter importer)
    {
        foreach (var platform in new[] { "Android", "iPhone", "Standalone" })
        {
            var settings = importer.GetPlatformSettings(platform);
            if (settings.overridden && IsAlphaFormat(settings.format))
                return true;
        }
        // 图集默认认为需要 Alpha(UI 图集大多有透明)
        return true;
    }
 
    /// <summary>
    /// 判断格式是否包含 Alpha 通道
    /// </summary>
    static bool IsAlphaFormat(TextureImporterFormat format)
    {
        switch (format)
        {
            case TextureImporterFormat.RGBA32:
            case TextureImporterFormat.RGBA16:
            case TextureImporterFormat.ARGB32:
            case TextureImporterFormat.ARGB16:
            case TextureImporterFormat.DXT5:
            case TextureImporterFormat.ETC2_RGBA8:
            case TextureImporterFormat.ASTC_4x4:
            case TextureImporterFormat.ASTC_5x5:
            case TextureImporterFormat.ASTC_6x6:
            case TextureImporterFormat.ASTC_8x8:
            case TextureImporterFormat.ASTC_10x10:
            case TextureImporterFormat.ASTC_12x12:
            case TextureImporterFormat.PVRTC_RGBA2:
            case TextureImporterFormat.PVRTC_RGBA4:
                return true;
            default:
                return false;
        }
    }
 
    /// <summary>
    /// 获取已有的最大贴图尺寸设置
    /// </summary>
    static int GetMaxTextureSize(TextureImporter importer)
    {
        foreach (var platform in new[] { "Android", "iPhone", "Standalone" })
        {
            var settings = importer.GetPlatformTextureSettings(platform);
            if (settings.overridden)
                return settings.maxTextureSize;
        }
        return importer.maxTextureSize;
    }
}