Project_WL/AgentScripts/WL814k_Survey2.cs

134 lines
6.8 KiB
C#

// WL-814k 실측 조사 ② — 조명 · Toon 머티리얼 매칭 · 샘플링 경로 (읽기만)
// run: unity command run_script --file AgentScripts/WL814k_Survey2.cs --entry WL814k_Survey2.Run
using System;
using System.Collections.Generic;
using System.IO;
using System.Text;
using UnityEditor;
using UnityEngine;
public static class WL814k_Survey2
{
const string kTxt = "AgentScripts/WL814k_SURVEY2.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"));
try
{
Lights();
ToonMatch("Assets/Res_Addr/PC/Ai01.prefab");
ToonMatch("Assets/Res_Addr/Mobs/Mob/Batty_A.prefab");
SamplePath();
Srp();
}
catch (Exception ex) { L("EXCEPTION " + ex); }
File.WriteAllText(kTxt, s_sb.ToString(), new UTF8Encoding(false));
Debug.Log("[WL814k] → " + kTxt);
}
// 게임 맵의 방향광 실측
static void Lights()
{
L("");
L("== 방향광 (Res_Addr/Map/WL_Nature.prefab + Ingame 씬) ==");
var map = AssetDatabase.LoadAssetAtPath<GameObject>("Assets/Res_Addr/Map/WL_Nature.prefab");
if (map != null)
{
foreach (var lt in map.GetComponentsInChildren<Light>(true))
L(string.Format(" [map] {0} type={1} color={2} intensity={3} shadows={4} euler={5}",
lt.name, lt.type, lt.color, lt.intensity, lt.shadows, lt.transform.eulerAngles.ToString("F2")));
}
else L(" WL_Nature.prefab 없음");
foreach (var sc in new[] { "Assets/Scenes/Ingame.unity", "Assets/Scenes/Title.unity" })
{
if (!File.Exists(sc)) { L(" " + sc + " 없음"); continue; }
var txt = File.ReadAllText(sc);
int i = txt.IndexOf("m_Type: 1");
L(" " + sc + " · Light(dir) 블록 " + (i >= 0 ? "있음" : "없음") + " · 파일 " + new FileInfo(sc).Length + " B");
}
L(" RenderSettings.ambientMode(현재 씬) = " + RenderSettings.ambientMode + " · ambientLight = " + RenderSettings.ambientLight
+ " · ambientIntensity = " + RenderSettings.ambientIntensity + " · sun = " + (RenderSettings.sun == null ? "null" : RenderSettings.sun.name));
}
// 캐릭터 머티리얼 → *_Toon.mat 존재 여부
static void ToonMatch(string prefab)
{
L("");
L("== Toon 매칭 " + prefab + " ==");
var go = AssetDatabase.LoadAssetAtPath<GameObject>(prefab);
if (go == null) { L(" 로드 실패"); return; }
var seen = new HashSet<string>();
foreach (var r in go.GetComponentsInChildren<Renderer>(true))
foreach (var m in r.sharedMaterials)
{
if (m == null || !seen.Add(m.name)) continue;
string toon = "Assets/WL/Look/Env/Materials/" + m.name + "_Toon.mat";
var t = AssetDatabase.LoadAssetAtPath<Material>(toon);
L(" " + m.name.PadRight(16) + " [" + (m.shader == null ? "-" : m.shader.name) + "] → " + (t != null ? "Toon 있음" : "Toon 없음"));
}
}
// 샘플링 경로 확인 — Generic/Humanoid 둘 다 AnimationMode 로 찍히는가
static void SamplePath()
{
L("");
L("== 샘플링 경로 (AnimationMode.SampleAnimationClip) ==");
foreach (var pair in new[] {
new[]{ "Assets/Res_Addr/PC/Ai01.prefab", "Idle" },
new[]{ "Assets/Res_Addr/Mobs/Mob/Batty_A.prefab", "Attack" } })
{
var go = AssetDatabase.LoadAssetAtPath<GameObject>(pair[0]);
if (go == null) { L(" " + pair[0] + " 로드 실패"); continue; }
var inst = (GameObject)PrefabUtility.InstantiatePrefab(go);
try
{
var anim = inst.GetComponentInChildren<Animator>(true);
AnimationClip clip = null;
foreach (var c in anim.runtimeAnimatorController.animationClips) if (c.name == pair[1]) { clip = c; break; }
if (clip == null) { L(" 클립 " + pair[1] + " 없음"); continue; }
// 대표 본의 t=0 / t=len/2 포즈 차이를 잰다
var bones = inst.GetComponentsInChildren<Transform>(true);
Transform probe = bones.Length > 3 ? bones[bones.Length / 2] : inst.transform;
AnimationMode.StartAnimationMode();
AnimationMode.BeginSampling();
AnimationMode.SampleAnimationClip(inst, clip, 0f);
AnimationMode.EndSampling();
Vector3 p0 = probe.localPosition; Quaternion r0 = probe.localRotation;
AnimationMode.BeginSampling();
AnimationMode.SampleAnimationClip(inst, clip, clip.length * 0.5f);
AnimationMode.EndSampling();
Vector3 p1 = probe.localPosition; Quaternion r1 = probe.localRotation;
AnimationMode.StopAnimationMode();
L(string.Format(" {0} · clip {1} · probe {2} · Δpos {3:0.0000} · Δrot {4:0.00}° → {5}",
Path.GetFileNameWithoutExtension(pair[0]), clip.name, probe.name,
Vector3.Distance(p0, p1), Quaternion.Angle(r0, r1),
(Vector3.Distance(p0, p1) > 0.0001f || Quaternion.Angle(r0, r1) > 0.05f) ? "샘플링 OK" : "변화 없음(확인필요)"));
}
catch (Exception ex) { L(" EXCEPTION " + ex.Message); if (AnimationMode.InAnimationMode()) AnimationMode.StopAnimationMode(); }
finally { UnityEngine.Object.DestroyImmediate(inst); }
}
}
static void Srp()
{
L("");
L("== 렌더 파이프라인 ==");
var rp = UnityEngine.Rendering.GraphicsSettings.defaultRenderPipeline;
L(" defaultRenderPipeline = " + (rp == null ? "null(빌트인)" : rp.name + " (" + AssetDatabase.GetAssetPath(rp) + ")"));
L(" currentRenderPipeline = " + (UnityEngine.Rendering.GraphicsSettings.currentRenderPipeline == null ? "null" : UnityEngine.Rendering.GraphicsSettings.currentRenderPipeline.name));
L(" QualitySettings.renderPipeline = " + (QualitySettings.renderPipeline == null ? "null" : QualitySettings.renderPipeline.name));
L(" SystemInfo.graphicsDeviceType = " + SystemInfo.graphicsDeviceType + " · supportsComputeShaders = " + SystemInfo.supportsComputeShaders);
L(" Application.isBatchMode = " + Application.isBatchMode);
// Unlit 투명 셰이더 후보
foreach (var s in new[] { "Sprites/Default", "Unlit/Transparent", "Universal Render Pipeline/Unlit", "Universal Render Pipeline/2D/Sprite-Unlit-Default" })
L(" Shader.Find(\"" + s + "\") = " + (Shader.Find(s) != null ? "OK" : "없음"));
}
}