// ───────────────────────────────────────────────────────────────────────────── // WLSpriteBakerWindow.cs — 「도트로 굽기」 에디터 창 (WL-814k · #814) // // 메뉴: WL ▸ 도트 스프라이트 굽기 // 🔴 캐릭터 이름이 코드에 0개 — 창에 **아무 캐릭터 프리팹이나** 끌어다 놓으면 그것을 굽는다. // (PD 가 캐릭터 에셋 교체를 검토 중 → 특정 프리팹에 하드코딩하지 않는다.) // ───────────────────────────────────────────────────────────────────────────── using System.Collections.Generic; using UnityEditor; using UnityEngine; namespace WL.Look.SpriteBake.EditorTools { public sealed class WLSpriteBakerWindow : EditorWindow { [SerializeField] List _targets = new List(); [SerializeField] WLSpriteBakeSettings _cfg; [SerializeField] string _outDir = ""; [SerializeField] Vector2 _scroll; [SerializeField] string _report = ""; [MenuItem("WL/도트 스프라이트 굽기 (3D → 도트 시트)", false, 30)] static void Open() { var w = GetWindow(false, "도트 굽기", true); w.minSize = new Vector2(460f, 360f); if (w._cfg == null) w._cfg = WLSpriteBakeSettings.Instance; w.Show(); } void OnGUI() { EditorGUILayout.HelpBox( "3D 캐릭터 프리팹을 인게임 도트 카메라와 같은 각도로 미리 렌더해서 스프라이트 시트(PNG) + 메타 SO 로 굽는다.\n" + "· 어떤 캐릭터 프리팹이든 아래 목록에 넣으면 된다(툴은 프리팹 이름을 모른다).\n" + "· 굽는 시점에 1px 외곽선 · 팔레트 양자화 · 알파 이진화를 강제한다.\n" + "· 원본 프리팹 / 머티리얼 / 애니메이션은 한 글자도 안 고친다(읽기·샘플링만).", MessageType.Info); _cfg = (WLSpriteBakeSettings)EditorGUILayout.ObjectField("굽기 설정(SO)", _cfg, typeof(WLSpriteBakeSettings), false); if (_cfg == null) { EditorGUILayout.HelpBox("Resources/WL/WLSpriteBakeSettings.asset 을 넣어라.", MessageType.Warning); if (GUILayout.Button("기본 설정 에셋 찾기")) _cfg = WLSpriteBakeSettings.Instance; return; } _outDir = EditorGUILayout.TextField(new GUIContent("출력 폴더(비우면 SO 값)"), _outDir); EditorGUILayout.LabelField(" → " + (string.IsNullOrEmpty(_outDir) ? _cfg.outputDir : _outDir), EditorStyles.miniLabel); EditorGUILayout.LabelField(string.Format(" 내림각 {0:0.000}° · 픽셀 1개 {1:0.00000} m · 방향 {2} · 프레임 {3}×{3}{4}", _cfg.PitchDeg, _cfg.WorldPerPixel, _cfg.dirCount, _cfg.frameSize, _cfg.autoFrameSize ? " (자동)" : ""), EditorStyles.miniLabel); EditorGUILayout.Space(); EditorGUILayout.LabelField("구울 프리팹 (드래그해서 넣기)", EditorStyles.boldLabel); var so = new SerializedObject(this); EditorGUILayout.PropertyField(so.FindProperty("_targets"), new GUIContent("대상"), true); so.ApplyModifiedProperties(); using (new EditorGUI.DisabledScope(_targets.Count == 0)) { if (GUILayout.Button("굽기 시작", GUILayout.Height(30f))) BakeAll(); } EditorGUILayout.Space(); _scroll = EditorGUILayout.BeginScrollView(_scroll); EditorGUILayout.TextArea(_report, GUILayout.ExpandHeight(true)); EditorGUILayout.EndScrollView(); } void BakeAll() { var sb = new System.Text.StringBuilder(); for (int i = 0; i < _targets.Count; i++) { var go = _targets[i]; if (go == null) continue; string path = AssetDatabase.GetAssetPath(go); if (string.IsNullOrEmpty(path)) { sb.AppendLine("건너뜀(프리팹 에셋이 아님): " + go.name); continue; } EditorUtility.DisplayProgressBar("도트로 굽는 중", path, (i + 0.5f) / _targets.Count); var r = WLSpriteBaker.Bake(path, _cfg, string.IsNullOrEmpty(_outDir) ? null : _outDir); sb.AppendLine((r.ok ? "OK " : "FAIL ") + r.Summary); sb.AppendLine(r.log.ToString()); foreach (var n in r.notes) sb.AppendLine(" · " + n); sb.AppendLine(); } EditorUtility.ClearProgressBar(); AssetDatabase.Refresh(); _report = sb.ToString(); Debug.Log("[WL814k] 굽기 완료\n" + _report); } } }