93 lines
5.0 KiB
C#
93 lines
5.0 KiB
C#
// ─────────────────────────────────────────────────────────────────────────────
|
||
// 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<GameObject> _targets = new List<GameObject>();
|
||
[SerializeField] WLSpriteBakeSettings _cfg;
|
||
[SerializeField] string _outDir = "";
|
||
[SerializeField] Vector2 _scroll;
|
||
[SerializeField] string _report = "";
|
||
|
||
[MenuItem("WL/도트 스프라이트 굽기 (3D → 도트 시트)", false, 30)]
|
||
static void Open()
|
||
{
|
||
var w = GetWindow<WLSpriteBakerWindow>(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);
|
||
}
|
||
}
|
||
}
|