Project_WL/AgentScripts/WL816b_Verify.cs

119 lines
6.6 KiB
C#
Raw Normal View History

// WL-816b — 최종 검증 (🔴 인게임 Play · 포스트 포함 · 게임 크기) · entry WL816bVerify.Run
// 실제 런타임 경로(`WLWeaponPalette.Apply`)로만 갈아끼운다 — 하니스 전용 경로를 쓰지 않는다.
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using UnityEngine;
using WL.Look.Character;
public static class WL816bVerify
{
public static void Run()
{
WL816b.Reset(); WL816b.PubSetup();
var cfg = WLCharacterPaletteSettings.Instance;
WL816b.Log("");
WL816b.Log("SO: enabled_=" + cfg.enabled_ + " weaponEnabled_=" + cfg.weaponEnabled_
+ " 무기행 " + (cfg.weaponNames == null ? 0 : cfg.weaponNames.Length)
+ " 캐릭터행 " + (cfg.rendererNames == null ? 0 : cfg.rendererNames.Length));
WL816b.Log("=== 최종 검증 (인게임 Play · 포스트 포함 · 1080x1920 · ortho 10 · 덩어리 6 · 팔레트 6칸) ===");
var cA = WL816b.MeasureChar("v_char_A.png", null);
WL816b.Log(string.Format("캐릭터 (무기 없음 · 시작) : {0} px · 고유색 {1} · 비율 {2:F2} % · 단계 {3}", cA.px, cA.uniq, cA.ratio, cA.steps));
WL816b.Log("");
WL816b.Log("| 무기 | 화면 px | 고유색 전→후 | 서로다른색 % 전→후 | 칸당단계 평균/최대 | 배수 | 메시/렌더러 교체 |");
WL816b.Log("|---|---|---|---|---|---|---|");
int okMesh = 0, okRend = 0;
foreach (var w in WL816b.WEAPONS)
{
WL816b.Clear();
float rb, mult;
var go = WL816b.Spawn(w[0], int.Parse(w[1]), out rb, out mult);
if (go == null) continue;
WL816b.ReLook();
var mA = WL816b.MeasureNow(go, "v_" + w[0] + "_maskA.png", "v_" + w[0] + "_A.png");
// 원본 메시·머티리얼 기록(되돌리기 동일성 확인용)
var mf0 = go.GetComponentsInChildren<MeshFilter>(true).Select(f => f.sharedMesh).ToArray();
var rm0 = go.GetComponentsInChildren<Renderer>(true).Where(r => !(r is ParticleSystemRenderer)).Select(r => r.sharedMaterial).ToArray();
WLWeaponPalette.ResetCounters();
WL816b.UnLook(); // 🔴 장식을 먼저 벗긴다
bool applied = WLWeaponPalette.Apply(go.transform); // 🔴 실제 런타임 경로
WL816b.ReLook();
var mB = WL816b.MeasureNow(go, "v_" + w[0] + "_maskB.png", "v_" + w[0] + "_B.png");
string steps = "—"; int mx = 0; float av = 0;
if (applied)
{
var mat = go.GetComponentsInChildren<Renderer>(true).First(r => !(r is ParticleSystemRenderer)).sharedMaterial;
var tex = mat.HasProperty("_BaseMap") ? mat.GetTexture("_BaseMap") as Texture2D : null;
if (tex != null)
{
// 팔레트 텍스처에서 칸 색을 되읽어 칸별 단계를 잰다
var pal = new List<Vector3>();
int G = tex.width / 8;
for (int j = 0; j < G * G; j++)
{
var c = tex.GetPixel((j % G) * 8 + 4, (j / G) * 8 + 4);
if (c.r > 0.98f && c.g < 0.02f && c.b > 0.98f) continue; // 미사용 칸(마젠타)
pal.Add(new Vector3(c.r, c.g, c.b));
}
string det = WL816b.CellSteps(go, pal.ToArray(), out mx, out av);
steps = av.ToString("F2") + "/" + mx;
WL816b.Log(" " + w[0] + " " + det);
}
okMesh += WLWeaponPalette.AppliedMeshes; okRend += WLWeaponPalette.AppliedRenderers;
}
WL816b.Log(string.Format("| {0} | {1} | {2}→{3} | {4:F2}→{5:F2} | {6} | ×{7:F4} | {8} |",
w[0], mB.px, mA.uniq, mB.uniq, mA.ratio, mB.ratio, steps, mult,
applied ? (WLWeaponPalette.AppliedMeshes + "/" + WLWeaponPalette.AppliedRenderers) : "표에 없음(Orb)"));
// 되돌리기 동일성 — 원본으로 되돌리면 글자 하나까지 같은가
if (applied)
{
WL816b.UnLook();
var fs = go.GetComponentsInChildren<MeshFilter>(true);
for (int i = 0; i < fs.Length; i++) fs[i].sharedMesh = mf0[i];
var rs = go.GetComponentsInChildren<Renderer>(true).Where(r => !(r is ParticleSystemRenderer)).ToArray();
for (int i = 0; i < rs.Length; i++) { var ms = rs[i].sharedMaterials; for (int k = 0; k < ms.Length; k++) ms[k] = rm0[i]; rs[i].sharedMaterials = ms; }
WL816b.ReLook();
var mR = WL816b.MeasureNow(go, null, "v_" + w[0] + "_R.png");
WL816b.Log(string.Format(" 되돌림 확인 {0} : px {1}(전 {2}) · 고유색 {3}(전 {4}) · {5}",
w[0], mR.px, mA.px, mR.uniq, mA.uniq, (mR.px == mA.px && mR.uniq == mA.uniq) ? "동일 ✅" : "차이 ⚠"));
}
}
WL816b.Clear();
var cB = WL816b.MeasureChar("v_char_B.png", null);
WL816b.Log("");
WL816b.Log(string.Format("캐릭터 (무기 없음 · 끝) : {0} px · 고유색 {1} · 비율 {2:F2} % · 단계 {3} → 악화 {4}",
cB.px, cB.uniq, cB.ratio, cB.steps, (cB.uniq <= cA.uniq && cB.ratio <= cA.ratio + 0.05f) ? "없음 ✅" : "고유색 " + (cB.uniq - cA.uniq) + " · 비율 " + (cB.ratio - cA.ratio).ToString("F2") + "%p"));
WL816b.Log("합계 교체: 메시 " + okMesh + " · 렌더러 " + okRend);
// ⓐⓑ 전신 캡처 — 기본 클래스(10501) 메이스+방패를 동시에 든 전신
WL816b.Clear();
float r1, m1, r2, m2;
var g1 = WL816b.Spawn("PP_Theme_10_Mace_003", 1, out r1, out m1);
var g2 = WL816b.Spawn("PP_Theme_10_Shield_003", 0, out r2, out m2);
WL816b.ReLook(); WL816b.ShootGame("a_full_before.png");
WL816b.UnLook();
WLWeaponPalette.Apply(g1.transform); WLWeaponPalette.Apply(g2.transform);
WL816b.ReLook(); WL816b.ShootGame("b_full_after.png");
// 한손검 전신도 한 장씩
WL816b.Clear();
var g3 = WL816b.Spawn("Elven_Sword_01", 2, out r1, out m1);
WL816b.ReLook(); WL816b.ShootGame("a_sword_before.png");
WL816b.UnLook();
WLWeaponPalette.Apply(g3.transform);
WL816b.ReLook(); WL816b.ShootGame("b_sword_after.png");
WL816b.Clear(); WL816b.FreeTmp(); WL816b.PubTeardown();
WL816b.Flush("WL816b_VERIFY.txt");
Debug.Log("[WL816b] verify done");
}
}