Project_WL/AgentScripts/WL814k_Naming.cs

110 lines
5.2 KiB
C#

// WL-814k 이름 규약 표 — 「굽기 SO 의 상태 이름 후보」가 어떤 캐릭터에 얼마나 걸리는지 실측 (읽기만 · 굽기 0)
// run: unity command run_script --file AgentScripts/WL814k_Naming.cs --entry WL814k_Naming.Run
// 🔴 여기서도 굽지 않는다 — 1차 시범은 PC 1종 + 잡몹 1종(발주서). 이 표는 「확장하면 뭐가 걸리나」의 근거다.
using System;
using System.Collections.Generic;
using System.IO;
using System.Text;
using UnityEditor;
using UnityEngine;
using WL.Look.SpriteBake;
public static class WL814k_Naming
{
const string kTxt = "AgentScripts/WL814k_NAMING.txt";
static StringBuilder s_sb;
static void L(string s) { s_sb.AppendLine(s); Debug.Log("[WL814k] " + s); }
public static void Run()
{
s_sb = new StringBuilder();
L("WL-814k 이름 규약 표 · " + DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"));
var cfg = AssetDatabase.LoadAssetAtPath<WLSpriteBakeSettings>("Assets/WL/Look/Sprite/Resources/WL/WLSpriteBakeSettings.asset");
if (cfg == null) { L("FAIL — 굽기 SO 없음"); File.WriteAllText(kTxt, s_sb.ToString(), new UTF8Encoding(false)); return; }
foreach (var a in cfg.actions)
L(" 후보 " + a.key.PadRight(7) + " = [" + string.Join(" / ", a.stateNames) + "] (+보기만: " + string.Join(" / ", a.alsoMapStateNames) + ")");
// ── ① 시범 2종 + PD 가 방금 임포트한 치비 팩(Little Heroes) ─────────────
L("");
L("== 개별 프리팹 ==");
foreach (var p in new[]
{
"Assets/Res_Addr/PC/Ai01.prefab",
"Assets/Res_Addr/Mobs/Mob/Batty_A.prefab",
"Assets/Suriyun/Characters/Nana/Prefab/F06.prefab",
"Assets/Suriyun/Characters/RedKnight/Prefab/M05/M05.prefab",
})
One(p, cfg);
// ── ② 몹 전수 — 확장했을 때 몇 %가 그냥 걸리는지 ───────────────────────
L("");
L("== Res_Addr/Mobs 전수 (확장 견적 근거) ==");
var guids = AssetDatabase.FindAssets("t:Prefab", new[] { "Assets/Res_Addr/Mobs" });
int total = 0, full = 0;
var hist = new Dictionary<int, int>();
var missing = new Dictionary<string, int>();
foreach (var g in guids)
{
var path = AssetDatabase.GUIDToAssetPath(g);
var go = AssetDatabase.LoadAssetAtPath<GameObject>(path);
if (go == null) continue;
var anim = go.GetComponentInChildren<Animator>(true);
if (anim == null || anim.runtimeAnimatorController == null) continue;
total++;
var states = States(anim);
int hit = 0;
foreach (var a in cfg.actions)
{
if (Match(a, states) != null) hit++;
else { int c; missing.TryGetValue(a.key, out c); missing[a.key] = c + 1; }
}
if (hit == cfg.actions.Length) full++;
int n; hist.TryGetValue(hit, out n); hist[hit] = n + 1;
}
L(" Animator+Controller 보유 프리팹 = " + total + " · 동작 5종 전부 매칭 = " + full + " (" + (100f * full / Mathf.Max(1, total)).ToString("0.0") + " %)");
var keys = new List<int>(hist.Keys); keys.Sort();
foreach (var k in keys) L(" 매칭 " + k + "/5 동작 = " + hist[k] + "종");
foreach (var kv in missing) L(" 못 찾은 동작 '" + kv.Key + "' = " + kv.Value + "종");
File.WriteAllText(kTxt, s_sb.ToString(), new UTF8Encoding(false));
Debug.Log("[WL814k] → " + kTxt);
}
static void One(string path, WLSpriteBakeSettings cfg)
{
var go = AssetDatabase.LoadAssetAtPath<GameObject>(path);
if (go == null) { L(" " + path + " → 없음"); return; }
var anim = go.GetComponentInChildren<Animator>(true);
if (anim == null || anim.runtimeAnimatorController == null) { L(" " + path + " → Animator/Controller 없음"); return; }
var states = States(anim);
var sb = new StringBuilder();
int hit = 0;
foreach (var a in cfg.actions)
{
var m = Match(a, states);
if (m != null) hit++;
sb.Append(a.key + "→" + (m ?? "✗") + " ");
}
L(string.Format(" {0,-56} 컨트롤러 {1,-24} 상태 {2,2}개 · 매칭 {3}/{4} · {5}",
Path.GetFileName(path), anim.runtimeAnimatorController.name, states.Count, hit, cfg.actions.Length, sb.ToString().Trim()));
}
static Dictionary<string, string> States(Animator anim)
{
var d = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase);
var ac = anim.runtimeAnimatorController as UnityEditor.Animations.AnimatorController;
if (ac != null && ac.layers.Length > 0 && ac.layers[0].stateMachine != null)
foreach (var ch in ac.layers[0].stateMachine.states)
if (ch.state.motion != null && !d.ContainsKey(ch.state.name)) d[ch.state.name] = ch.state.name;
return d;
}
static string Match(WLSpriteBakeAction a, Dictionary<string, string> states)
{
foreach (var n in a.stateNames) { string real; if (states.TryGetValue(n, out real)) return real; }
return null;
}
}