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;
|
}
|
}
|