using System.Linq; using UnityEditor; using UnityEngine; public class SpritePostprocessor : AssetPostprocessor { private static void OnPostprocessAllAssets( string[] importedAssets, string[] deletedAssets, string[] movedAssets, string[] movedFromAssetPaths) { var config = AtlasConfiguration.Instance; if (!config.autoGenerate) return; try { ProcessAssetChanges( importedAssets: importedAssets, deletedAssets: deletedAssets, movedAssets: movedAssets, movedFromPaths: movedFromAssetPaths ); } catch (System.Exception e) { Debug.LogError($"Atlas processing error: {e.Message}\n{e.StackTrace}"); } finally { AssetDatabase.Refresh(); } } private static void ProcessAssetChanges( string[] importedAssets, string[] deletedAssets, string[] movedAssets, string[] movedFromPaths) { ProcessAssets(importedAssets, (path) => { EditorSpriteSaveInfo.ConvertToSprite(path); EditorSpriteSaveInfo.OnImportSprite(path); LogProcessed("[Added]", path); }); ProcessAssets(deletedAssets, (path) => { EditorSpriteSaveInfo.OnDeleteSprite(path); LogProcessed("[Deleted]", path); }); ProcessMovedAssets(movedFromPaths, movedAssets); } private static void ProcessAssets(string[] assets, System.Action processor) { if (assets == null) return; foreach (var asset in assets) { if (ShouldProcessAsset(asset)) { processor?.Invoke(asset); } } } private static void ProcessMovedAssets(string[] oldPaths, string[] newPaths) { if (oldPaths == null || newPaths == null) return; for (int i = 0; i < oldPaths.Length; i++) { if (ShouldProcessAsset(oldPaths[i])) { EditorSpriteSaveInfo.OnDeleteSprite(oldPaths[i]); LogProcessed("[Moved From]", oldPaths[i]); EditorSpriteSaveInfo.MarkParentAtlasesDirty(oldPaths[i]); } if (ShouldProcessAsset(newPaths[i])) { EditorSpriteSaveInfo.OnImportSprite(newPaths[i]); LogProcessed("[Moved To]", newPaths[i]); EditorSpriteSaveInfo.MarkParentAtlasesDirty(newPaths[i]); } } } private static bool ShouldProcessAsset(string assetPath) { var config = AtlasConfiguration.Instance; if (string.IsNullOrEmpty(assetPath)) return false; if (assetPath.StartsWith("Packages/")) return false; if (!assetPath.StartsWith(config.sourceAtlasRoot)) return false; if (config.excludeFolders.Any(assetPath.StartsWith)) return false; if (!IsValidImageFile(assetPath)) return false; foreach (var keyword in config.excludeKeywords) { if (assetPath.IndexOf(keyword, System.StringComparison.OrdinalIgnoreCase) >= 0) return false; } return true; } private static bool IsValidImageFile(string path) { var ext = System.IO.Path.GetExtension(path).ToLower(); return ext switch { ".png" => true, ".jpg" => true, ".jpeg" => true, _ => false }; } private static void LogProcessed(string operation, string path) { if (AtlasConfiguration.Instance.enableLogging) { Debug.Log($"{operation} {System.IO.Path.GetFileName(path)}\nPath: {path}"); } } }