// WL824_ImportRefSprites.cs — XP Hero 더미 스프라이트 임포터 일괄 설정 (2026-10-09 · 로컬 전용 폴더) // 실행(반복): unity command run_script --file AgentScripts/WL824_ImportRefSprites.cs --entry WL824_ImportRefSprites.Run --timeout 120 // 메인 스레드 30초 한도 때문에 한 번에 BatchSize 장만 처리하고 "remaining N" 을 돌려준다 → 0 이 될 때까지 반복. // Sprite(Single) · PPU 100 · 9-slice 테두리 = sprite_borders.csv(원본 m_Border: L,B,R,T) · 밉맵 off · 비압축 using System.IO; using System.Text; using System.Collections.Generic; using UnityEditor; using UnityEngine; public static class WL824_ImportRefSprites { const string Folder = "Assets/WL/UI/RefDummy_XPHero/Resources/XPHeroRef"; const string Csv = "Assets/WL/UI/RefDummy_XPHero/sprite_borders.csv"; const int BatchSize = 40; static float F(string s) { float v; return float.TryParse(s, System.Globalization.NumberStyles.Float, System.Globalization.CultureInfo.InvariantCulture, out v) ? v : 0f; } static Dictionary LoadBorders() { var borders = new Dictionary(); if (!File.Exists(Csv)) return borders; var lines = File.ReadAllLines(Csv); for (int i = 1; i < lines.Length; i++) { var c = lines[i].Split(','); if (c.Length < 11) continue; borders[c[0]] = new Vector4(F(c[2]), F(c[3]), F(c[4]), F(c[5])); } return borders; } static bool IsDone(TextureImporter imp, Vector4 want) { if (imp.textureType != TextureImporterType.Sprite) return false; if (imp.mipmapEnabled) return false; var b = imp.spriteBorder; return (b - want).sqrMagnitude < 0.01f; } public static string Run() { AssetDatabase.Refresh(); // 새로 복사된 PNG 가 아직 임포트되지 않았으면 importer 가 없다 var borders = LoadBorders(); var files = Directory.GetFiles(Folder, "*.png"); int done = 0, todo = 0, processed = 0, nb = 0; var sb = new StringBuilder(); var pending = new List(); foreach (var path in files) { var ap = path.Replace('\\', '/'); var imp = AssetImporter.GetAtPath(ap) as TextureImporter; if (imp == null) { sb.Append("no importer: ").Append(Path.GetFileName(ap)).Append(' '); continue; } Vector4 want; if (!borders.TryGetValue(Path.GetFileNameWithoutExtension(ap), out want)) want = Vector4.zero; if (IsDone(imp, want)) { done++; continue; } todo++; if (pending.Count < BatchSize) pending.Add(ap); } if (pending.Count > 0) { AssetDatabase.StartAssetEditing(); try { foreach (var ap in pending) { var imp = AssetImporter.GetAtPath(ap) as TextureImporter; if (imp == null) continue; var key = Path.GetFileNameWithoutExtension(ap); imp.textureType = TextureImporterType.Sprite; imp.spriteImportMode = SpriteImportMode.Single; imp.spritePixelsPerUnit = 100f; imp.mipmapEnabled = false; imp.alphaIsTransparency = true; imp.filterMode = FilterMode.Bilinear; imp.npotScale = TextureImporterNPOTScale.None; imp.textureCompression = TextureImporterCompression.Uncompressed; imp.maxTextureSize = 1024; Vector4 b; if (borders.TryGetValue(key, out b) && (b.x > 0 || b.y > 0 || b.z > 0 || b.w > 0)) { imp.spriteBorder = b; nb++; } else imp.spriteBorder = Vector4.zero; imp.SaveAndReimport(); processed++; } } finally { AssetDatabase.StopAssetEditing(); } } return "files " + files.Length + " · already done " + done + " · processed now " + processed + " (9-slice " + nb + ") · remaining " + (todo - processed) + (sb.Length > 0 ? "\n" + sb : ""); } }