From 3f9fd4227a225e798e047fef9e9e4dc45b3900b3 Mon Sep 17 00:00:00 2001 From: NTG_Lenovo Date: Fri, 4 Jul 2025 18:21:11 +0900 Subject: [PATCH] =?UTF-8?q?AssetPostProcessors=20Pivot=20=EC=9E=90?= =?UTF-8?q?=EB=8F=99=20=EB=B3=80=EA=B2=BD=20=EB=A1=9C=EC=A7=81=20=EC=B6=94?= =?UTF-8?q?=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../AssetPostProcessors.cs | 28 ++++++-- .../AssetPostprocessorSprite.cs | 70 +++++++++++++++++-- 2 files changed, 90 insertions(+), 8 deletions(-) diff --git a/Assets/_Datas/02.Scripts/AssetPostprocessors/AssetPostProcessors.cs b/Assets/_Datas/02.Scripts/AssetPostprocessors/AssetPostProcessors.cs index 9475a2cfc..ce9dcaa6a 100644 --- a/Assets/_Datas/02.Scripts/AssetPostprocessors/AssetPostProcessors.cs +++ b/Assets/_Datas/02.Scripts/AssetPostprocessors/AssetPostProcessors.cs @@ -1,6 +1,7 @@ #if UNITY_EDITOR using UnityEngine; using UnityEditor; +using UnityEngine.Networking; namespace DDD { @@ -16,15 +17,34 @@ private void OnPreprocessTexture() // { // AssetPostprocessorModel.OnPreprocessTexture(importer); // } - + Debug.Log(upperPath); if (upperPath.Contains("ASSETS/_DATAS/RAW/SPRITES/")) { AssetPostprocessorSprite.OnPreprocessTexture(importer); } } - - public static void OnPostprocessAllAssets(string[] importedAssets, string[] deleteAssets, string[] movedAssets, string[] movedFromAssetPaths) + + public static void OnPostprocessAllAssets(string[] importedAssets, string[] deleteAssets, string[] movedAssets, + string[] movedFromAssetPaths) { + for (int i = 0; i < movedAssets.Length; i++) + { + string fromPath = movedFromAssetPaths[i]; + string toPath = movedAssets[i]; + + // 특정 폴더일 때만 작동 + if (toPath.StartsWith("Assets/_Datas/Raw/Sprites/")) + { + if (AssetDatabase.LoadAssetAtPath(toPath) == null) + { + Debug.Log($"에셋 이동 감지: {fromPath} → {toPath}"); + + // 여기서 임포트 강제 재실행 + AssetDatabase.ImportAsset(toPath, ImportAssetOptions.ForceUpdate); + } + } + } + foreach (var path in deleteAssets) { PostRemove(path); @@ -50,7 +70,7 @@ public static void OnPostprocessAllAssets(string[] importedAssets, string[] dele AssetPostprocessorSprite.BuildTarget(); AssetPostprocessorSprite.BuildTarget(); } - + private static void PostRemove(string path, string movePath = "") { try diff --git a/Assets/_Datas/02.Scripts/AssetPostprocessors/AssetPostprocessorSprite.cs b/Assets/_Datas/02.Scripts/AssetPostprocessors/AssetPostprocessorSprite.cs index d8cc6e923..7fec1f7c2 100644 --- a/Assets/_Datas/02.Scripts/AssetPostprocessors/AssetPostprocessorSprite.cs +++ b/Assets/_Datas/02.Scripts/AssetPostprocessors/AssetPostprocessorSprite.cs @@ -22,7 +22,7 @@ public static void OnPreprocessTexture(TextureImporter importer) importer.spritePixelsPerUnit = width <= height ? width : height; importer.sRGBTexture = true; - importer.isReadable = false; + importer.isReadable = true; importer.mipmapEnabled = false; importer.streamingMipmaps = false; importer.wrapMode = TextureWrapMode.Clamp; @@ -36,6 +36,66 @@ public static void OnPreprocessTexture(TextureImporter importer) textureSettings.spriteMeshType = SpriteMeshType.FullRect; textureSettings.spriteExtrude = 2; importer.SetTextureSettings(textureSettings); + + string path = importer.assetPath; + EditorApplication.delayCall += () => { TryApplyPivotAfterImport(path); }; + } + + private static void TryApplyPivotAfterImport(string path) + { + if (string.IsNullOrEmpty(path)) return; + + // ✅ 무한 루프 방지 플래그 확인 + string sessionKey = $"__SPRITE_PIVOT_SET__{path}"; + if (SessionState.GetBool(sessionKey, false)) + { + SessionState.EraseBool(sessionKey); + return; // 이미 한 번 처리한 경우 재진입 금지 + } + + var texture = AssetDatabase.LoadAssetAtPath(path); + if (texture == null || !texture.isReadable) return; + + int height = texture.height; + int width = texture.width; + int bottomY = height; + + for (int y = 0; y < height; y++) + { + for (int x = 0; x < width; x++) + { + if (texture.GetPixel(x, y).a > 0.01f) + { + bottomY = y; + goto FOUND_ALPHA; + } + } + } + + FOUND_ALPHA: + if (bottomY == height) + { + Debug.LogWarning($"[SpritePivot] 모든 픽셀이 투명하여 pivot 설정 생략: {path}"); + return; + } + + float pivotY = (float)bottomY / height; + + var importer = AssetImporter.GetAtPath(path) as TextureImporter; + if (importer == null) return; + + var settings = new TextureImporterSettings(); + importer.ReadTextureSettings(settings); + + settings.spriteAlignment = (int)SpriteAlignment.Custom; + settings.spritePivot = new Vector2(0.5f, pivotY); + importer.SetTextureSettings(settings); + + Debug.Log($"[SpritePivot] {path} → pivotY = {pivotY:F2}"); + + // ✅ 재임포트 플래그 설정 후 실행 (한 번만) + SessionState.SetBool(sessionKey, true); + AssetDatabase.ImportAsset(path, ImportAssetOptions.ForceUpdate); } public static void OnRemove(string path, string movePath) @@ -186,11 +246,11 @@ public static void CreatePrefab(string path, string destPath) prefab.name = sprite.name; GameObject visualLook = new GameObject("VisualLook"); - + visualLook.transform.SetParent(prefab.transform); visualLook.transform.localPosition = Vector3.zero; visualLook.transform.localRotation = Quaternion.Euler(new Vector3(40f, 0f, 0f)); - + SpriteRenderer spriteRenderer = visualLook.AddComponent(); spriteRenderer.sprite = sprite; spriteRenderer.sortingOrder = 5; @@ -280,10 +340,12 @@ public static void BuildTarget() { foreach (var path in TargetPaths) { - CreateAtlas(Utils.FolderPath(path), Utils.FolderPath(path).Replace("/Raw/", "/Addressables/") + ".spriteatlasv2"); + CreateAtlas(Utils.FolderPath(path), + Utils.FolderPath(path).Replace("/Raw/", "/Addressables/") + ".spriteatlasv2"); CreatePrefab(path, (path.Replace("/Raw/Sprites/", "/Addressables/") + ".prefab").Replace(".png", "")); } + TargetPaths.Clear(); } }