Project_WL/AgentScripts/WL814k_Diag3.cs

139 lines
7.4 KiB
C#
Raw Permalink Normal View History

// WL-814k 진단 ③ — AnimationMode 샘플링이 실루엣을 어떻게 바꾸는지 프레임별 실측
// run: unity command run_script --file AgentScripts/WL814k_Diag3.cs --entry WL814k_Diag3.Run
using System;
using System.IO;
using System.Text;
using UnityEditor;
using UnityEditor.SceneManagement;
using UnityEngine;
public static class WL814k_Diag3
{
const string kTxt = "AgentScripts/WL814k_DIAG3.txt";
static string OutDir = @"E:\NerdNavis\nn_himminji\Screenshots_WL\WL814k_diag";
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();
Directory.CreateDirectory(OutDir);
L("WL-814k 진단 ③ · " + DateTime.Now.ToString("HH:mm:ss"));
Test("Assets/Res_Addr/PC/Ai01.prefab", new[] { "Idle", "Run", "Atk2_wing", "LightHit", "death_F3441" });
File.WriteAllText(kTxt, s_sb.ToString(), new UTF8Encoding(false));
Debug.Log("[WL814k] → " + kTxt);
}
static void Test(string prefabPath, string[] clipNames)
{
GameObject pivot = null, inst = null, camGo = null;
RenderTexture rt = null; Texture2D tex = null;
bool am = false;
try
{
EditorSceneManager.NewScene(NewSceneSetup.EmptyScene, NewSceneMode.Single);
RenderSettings.ambientMode = UnityEngine.Rendering.AmbientMode.Flat;
RenderSettings.ambientLight = new Color(0.212f, 0.227f, 0.259f, 1f);
RenderSettings.fog = false; RenderSettings.skybox = null;
var sun = new GameObject("Sun").AddComponent<Light>();
sun.type = LightType.Directional; sun.intensity = 1.2f; sun.shadows = LightShadows.None;
sun.transform.rotation = Quaternion.Euler(26.4f, 238.6f, 0f);
var src = AssetDatabase.LoadAssetAtPath<GameObject>(prefabPath);
pivot = new GameObject("Pivot");
inst = (GameObject)PrefabUtility.InstantiatePrefab(src);
PrefabUtility.UnpackPrefabInstance(inst, PrefabUnpackMode.Completely, InteractionMode.AutomatedAction);
inst.transform.SetParent(pivot.transform, false);
inst.transform.localPosition = Vector3.zero; inst.transform.localRotation = Quaternion.identity;
foreach (var c in inst.GetComponentsInChildren<Collider>(true)) UnityEngine.Object.DestroyImmediate(c);
foreach (var c in inst.GetComponentsInChildren<UnityEngine.AI.NavMeshAgent>(true)) UnityEngine.Object.DestroyImmediate(c);
foreach (var c in inst.GetComponentsInChildren<Rigidbody>(true)) UnityEngine.Object.DestroyImmediate(c);
foreach (var c in inst.GetComponentsInChildren<ParticleSystem>(true)) UnityEngine.Object.DestroyImmediate(c.gameObject);
foreach (var mb in inst.GetComponentsInChildren<MonoBehaviour>(true)) if (mb != null) UnityEngine.Object.DestroyImmediate(mb);
var anim = inst.GetComponent<Animator>();
L(" Animator 살아있나 = " + (anim != null));
float wpp = 3.4f * 2f / 240f;
int P = 192;
camGo = new GameObject("Cam");
var cam = camGo.AddComponent<Camera>();
cam.orthographic = true; cam.orthographicSize = P * wpp * 0.5f;
cam.nearClipPlane = 0.01f; cam.farClipPlane = 200f;
cam.clearFlags = CameraClearFlags.SolidColor; cam.allowHDR = false; cam.allowMSAA = false;
camGo.transform.rotation = Quaternion.Euler(43.609f, 0f, 0f);
camGo.transform.position = -camGo.transform.right * (wpp * 0.5f) - camGo.transform.up * (wpp * 0.5f) - camGo.transform.forward * 50f;
rt = new RenderTexture(P, P, 24, RenderTextureFormat.ARGB32, RenderTextureReadWrite.sRGB);
rt.filterMode = FilterMode.Point; rt.antiAliasing = 1; rt.Create();
tex = new Texture2D(P, P, TextureFormat.RGBA32, false, false);
var rac = anim.runtimeAnimatorController;
var black = new Color32[P * P]; var white = new Color32[P * P];
// ⓐ 샘플링 없이
Box(cam, rt, tex, P, black, white, "샘플링 없음", null);
AnimationMode.StartAnimationMode(); am = true;
foreach (var name in clipNames)
{
AnimationClip clip = null;
foreach (var c in rac.animationClips) if (c.name == name) { clip = c; break; }
if (clip == null) { L(" 클립 " + name + " 없음"); continue; }
for (int f = 0; f < 4; f++)
{
float t = clip.length * f / 4f;
AnimationMode.BeginSampling();
AnimationMode.SampleAnimationClip(inst, clip, t);
AnimationMode.EndSampling();
inst.transform.localPosition = Vector3.zero;
inst.transform.localRotation = Quaternion.identity;
string tag = name + "_f" + f;
Box(cam, rt, tex, P, black, white, tag, (name == "Idle" && f == 0) ? OutDir + "\\am_" + tag + ".png" : null);
L(" 루트 localPos " + inst.transform.localPosition.ToString("F3") + " · lossyScale " + inst.transform.lossyScale.ToString("F3"));
}
}
AnimationMode.StopAnimationMode(); am = false;
}
catch (Exception ex) { L("EXCEPTION " + ex); }
finally
{
if (am && AnimationMode.InAnimationMode()) AnimationMode.StopAnimationMode();
if (rt != null) { RenderTexture.active = null; rt.Release(); UnityEngine.Object.DestroyImmediate(rt); }
if (tex != null) UnityEngine.Object.DestroyImmediate(tex);
if (camGo != null) UnityEngine.Object.DestroyImmediate(camGo);
if (pivot != null) UnityEngine.Object.DestroyImmediate(pivot);
EditorSceneManager.NewScene(NewSceneSetup.EmptyScene, NewSceneMode.Single);
}
}
static void Box(Camera cam, RenderTexture rt, Texture2D tex, int P, Color32[] black, Color32[] white, string tag, string savePng)
{
Grab(cam, rt, tex, P, Color.black, black, savePng == null ? null : savePng.Replace(".png", "_black.png"));
Grab(cam, rt, tex, P, Color.white, white, savePng == null ? null : savePng.Replace(".png", "_white.png"));
int cov = 0, minX = int.MaxValue, maxX = -1, minY = int.MaxValue, maxY = -1;
for (int y = 0; y < P; y++)
for (int x = 0; x < P; x++)
{
int i = y * P + x;
float c = 1f - (((white[i].r - black[i].r) + (white[i].g - black[i].g) + (white[i].b - black[i].b)) / 765f);
if (c < 0.5f) continue;
cov++;
if (x < minX) minX = x; if (x > maxX) maxX = x;
if (y < minY) minY = y; if (y > maxY) maxY = y;
}
L(string.Format(" {0,-18} 덮인 {1,6} · x[{2}..{3}] y[{4}..{5}]", tag, cov, minX, maxX, minY, maxY));
}
static void Grab(Camera cam, RenderTexture rt, Texture2D tex, int P, Color bg, Color32[] outPx, string file)
{
cam.backgroundColor = bg;
cam.targetTexture = rt; cam.Render(); cam.targetTexture = null;
var active = RenderTexture.active; RenderTexture.active = rt;
tex.ReadPixels(new Rect(0, 0, P, P), 0, 0); tex.Apply(false, false);
RenderTexture.active = active;
if (file != null) File.WriteAllBytes(file, tex.EncodeToPNG());
Array.Copy(tex.GetPixels32(), outPx, outPx.Length);
}
}