| Assets/Editor/Tool/TexturePlatformAssetPostprocessor.cs | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
| Assets/Editor/Tool/TexturePlatformFormatHelper.cs | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
| Assets/Editor/Tool/UpdateSpritePackingSetting.cs | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 |
Assets/Editor/Tool/TexturePlatformAssetPostprocessor.cs
@@ -15,6 +15,11 @@ private static readonly string TARGET_FOLDER = TexturePlatformFormatHelper.TARGET_FOLDER; private static readonly bool AUTO_APPLY_ATLAS_SETTINGS = true; /// <summary> /// 防止回调中 SaveAndReimport 同步触发下一次 OnPostprocessAllAssets 造成嵌套重入。 /// </summary> private static bool s_IsApplying; void OnPreprocessTexture() { if (!assetPath.StartsWith(TARGET_FOLDER)) @@ -38,30 +43,41 @@ { if (!AUTO_APPLY_ATLAS_SETTINGS) return; // 回调里的 SaveAndReimport 会同步再次触发本回调,必须挡掉,否则会无限自触发 if (s_IsApplying) return; foreach (var assetPath in importedAssets) s_IsApplying = true; try { if (!assetPath.StartsWith(TARGET_FOLDER)) continue; if (!assetPath.EndsWith(".spriteatlasv2") && !assetPath.EndsWith(".spriteatlas")) continue; try foreach (var assetPath in importedAssets) { var importer = SpriteAtlasImporter.GetAtPath(assetPath) as SpriteAtlasImporter; if (importer == null) if (!assetPath.StartsWith(TARGET_FOLDER)) continue; if (!assetPath.EndsWith(".spriteatlasv2") && !assetPath.EndsWith(".spriteatlas")) continue; if (TexturePlatformFormatHelper.ApplyAtlasPlatformSettings(importer)) try { importer.SaveAndReimport(); Debug.Log($"[TexImport] 图集: {assetPath}"); var importer = SpriteAtlasImporter.GetAtPath(assetPath) as SpriteAtlasImporter; if (importer == null) continue; if (TexturePlatformFormatHelper.ApplyAtlasPlatformSettings(importer)) { importer.SaveAndReimport(); Debug.Log($"[TexImport] 图集: {assetPath}"); } } catch (System.Exception ex) { Debug.LogError($"[TexImport] 图集失败 {assetPath}: {ex.Message}"); } } catch (System.Exception ex) { Debug.LogError($"[TexImport] 图集失败 {assetPath}: {ex.Message}"); } } finally { s_IsApplying = false; } } } Assets/Editor/Tool/TexturePlatformFormatHelper.cs
@@ -142,15 +142,28 @@ return changed; } /// <summary> /// 会被真正写入 meta 的图集平台(只有 overridden=true 的平台设置才会被持久化)。 /// Standalone / DefaultTexturePlatform 按需求保持默认,不做覆盖。 /// </summary> public static readonly string[] OVERRIDDEN_ATLAS_PLATFORMS = { "Android", "iPhone", "WebGL" }; /// <summary> /// 统一图集平台的 maxTextureSize。 /// 注意:绝不能对 overridden=false 的平台写 maxTextureSize —— 这类设置不会被持久化, /// 每次导入读回来仍是默认值,会被判成"有改动"从而在 OnPostprocessAllAssets 里反复 /// SaveAndReimport,最终触发 Unity 的 "infinite import loop" 检测。 /// </summary> public static bool ApplyAtlasMaxTextureSize(SpriteAtlasImporter importer) { bool changed = false; foreach (var platform in new[] { "Standalone", "Android", "iPhone", "WebGL", "DefaultTexturePlatform" }) foreach (var platform in OVERRIDDEN_ATLAS_PLATFORMS) { var settings = importer.GetPlatformSettings(platform); if (settings.maxTextureSize == ATLAS_MAX_SIZE) if (settings.overridden && settings.maxTextureSize == ATLAS_MAX_SIZE) continue; settings.overridden = true; settings.maxTextureSize = ATLAS_MAX_SIZE; importer.SetPlatformSettings(settings); changed = true; Assets/Editor/Tool/UpdateSpritePackingSetting.cs
@@ -13,8 +13,34 @@ static string rootPath = Application.dataPath + "/ResourcesOut/Sprite"; static string spriteRelativePath = "Assets/ResourcesOut/Sprite"; /// <summary> /// 图集处理流程的重入保护:流程内部会大量 SaveAndReimport / ImportAsset, /// 这些都会触发 AssetPostprocessor,若不挡住重入就会与批处理/菜单触发形成互相导入。 /// </summary> private static bool s_IsRunning; [MenuItem("程序/Sprite/标准化Sprite设置")] public static void UpdateAllSpritePackingSetting() { if (s_IsRunning) { Debug.LogWarning("[SpritePack] 上一次图集处理尚未结束,已跳过本次调用"); return; } s_IsRunning = true; try { UpdateAllSpritePackingSettingInternal(); } finally { s_IsRunning = false; EditorUtility.ClearProgressBar(); } } private static void UpdateAllSpritePackingSettingInternal() { var path = "Assets/Editor/SpritePacking/SpriteSettings.asset"; var so = AssetDatabase.LoadAssetAtPath<SpriteSettingConfig>(path); @@ -107,7 +133,7 @@ EditorUtility.ClearProgressBar(); SpritePack(); SpritePackInternal(); } [MenuItem("程序/Sprite/打包BuiltIn图集")] @@ -151,6 +177,11 @@ } }; spriteAtlas = CreateSpriteAtlas(spriteRelativePath_BuiltIn, setting); if (spriteAtlas == null) { Debug.LogError($"[SpritePack] 创建 BuiltIn 图集失败: {builtInSpritePath}"); return; } } List<string> excludePngs = new List<string>() { "Launch_1.png", "Launch_2.png", "Launch_3.png", "LoginBackGround.png", "TB_DL_Logo.png" }; @@ -166,6 +197,26 @@ [MenuItem("程序/Sprite/打包图集")] public static void SpritePack() { if (s_IsRunning) { Debug.LogWarning("[SpritePack] 上一次图集处理尚未结束,已跳过本次调用"); return; } s_IsRunning = true; try { SpritePackInternal(); } finally { s_IsRunning = false; EditorUtility.ClearProgressBar(); } } private static void SpritePackInternal() { var path = "Assets/Editor/SpritePacking/SpriteSettings.asset"; var so = AssetDatabase.LoadAssetAtPath<SpriteSettingConfig>(path); @@ -195,6 +246,11 @@ if (spriteAtlas == null) { spriteAtlas = CreateSpriteAtlas(spriteRelativePath, setting); if (spriteAtlas == null) { Debug.LogError($"[SpritePack] 创建图集失败: {filePath}"); continue; } } string spriteFilePath = rootPath + "/" + spritefilePathName; @@ -233,8 +289,12 @@ string atlasPath = outPath + "/" + setting.folderName + ".spriteatlasv2"; CreateEmptySpriteAtlas(atlasPath); SpriteAtlasImporter atlasImporter = SpriteAtlasImporter.GetAtPath(atlasPath) as SpriteAtlasImporter; if (atlasImporter == null) { Debug.LogError($"[SpritePack] 获取 SpriteAtlasImporter 失败: {atlasPath}"); return null; } #region 图集基础设置 @@ -288,7 +348,11 @@ { SpriteAtlasAsset.Save(new SpriteAtlasAsset(), atlasPath); AssetDatabase.SaveAssets(); AssetDatabase.Refresh(); // 这里只能用精确导入,不能调用 AssetDatabase.Refresh(): // 全库刷新会把刚写入的图集再次推入导入流程,进而触发 OnPostprocessAllAssets, // 被 Unity 判定为 "infinite import loop"(ZZBF.spriteatlasv2 反复 changed)。 AssetDatabase.ImportAsset(atlasPath, ImportAssetOptions.ForceSynchronousImport); } @@ -308,6 +372,11 @@ FileName(spriteFilePath, excludePng); SpriteAtlas spriteAtlasTmp = AssetDatabase.LoadAssetAtPath(filePath, typeof(UnityEngine.Object)) as SpriteAtlas; if (spriteAtlasTmp == null) { Debug.LogError($"[SpritePack] 无法加载图集,跳过更新: {filePath}"); return; } // 获取图集下图片 List<UnityEngine.Object> packables = new List<UnityEngine.Object>(spriteAtlasTmp.GetPackables());