Project_WL/AgentScripts/WL816a_Probe.cs

157 lines
9.1 KiB
C#
Raw Permalink Normal View History

// WL-816a 실측 프로브 — 씬의 렌더링 구성 전수 + 에디트 모드 오프스크린 캡처
// 원본은 한 글자도 고치지 않는다(열기만 하고 저장 안 함).
public static class WL816a_Probe
{
// ── 씬 1개 전수 조사 ────────────────────────────────────────────────
public static void Run()
{
string[] scenes =
{
"Assets/FarmingIsland/Scenes/Level01.unity",
"Assets/3DPixelArtEnvironment/Demo/Demo.unity",
};
var sb = new System.Text.StringBuilder();
for (int i = 0; i < scenes.Length; i++) Scan(scenes[i], sb);
UnityEngine.Debug.Log(sb.ToString());
}
public static void Scan(string path, System.Text.StringBuilder sb)
{
var sc = UnityEditor.SceneManagement.EditorSceneManager.OpenScene(
path, UnityEditor.SceneManagement.OpenSceneMode.Single);
Report(path, sb);
}
public static void Report(string label, System.Text.StringBuilder sb)
{
var rends = UnityEngine.Object.FindObjectsByType<UnityEngine.Renderer>(
UnityEngine.FindObjectsInactive.Exclude, UnityEngine.FindObjectsSortMode.None);
var mats = new System.Collections.Generic.Dictionary<UnityEngine.Material, int>();
var shaders = new System.Collections.Generic.Dictionary<string, int>();
var texMats = new System.Collections.Generic.List<string>();
long tris = 0; int slots = 0; int nMeshRend = 0, nSkinned = 0, nPart = 0;
for (int i = 0; i < rends.Length; i++)
{
var r = rends[i];
if (r is UnityEngine.ParticleSystemRenderer) { nPart++; continue; }
var mr = r as UnityEngine.MeshRenderer;
var sk = r as UnityEngine.SkinnedMeshRenderer;
UnityEngine.Mesh mesh = null;
if (mr != null) { nMeshRend++; var mf = r.GetComponent<UnityEngine.MeshFilter>(); if (mf != null) mesh = mf.sharedMesh; }
else if (sk != null) { nSkinned++; mesh = sk.sharedMesh; }
if (mesh != null) { for (int s = 0; s < mesh.subMeshCount; s++) tris += mesh.GetIndexCount(s) / 3; }
var ms = r.sharedMaterials;
for (int m = 0; m < ms.Length; m++)
{
if (ms[m] == null) continue;
slots++;
int c; mats.TryGetValue(ms[m], out c); mats[ms[m]] = c + 1;
string sn = ms[m].shader != null ? ms[m].shader.name : "<null>";
int c2; shaders.TryGetValue(sn, out c2); shaders[sn] = c2 + 1;
}
}
foreach (var kv in mats)
{
var m = kv.Key;
string tex = "";
if (m.HasProperty("_BaseMap") && m.GetTexture("_BaseMap") != null) tex += "BaseMap=" + m.GetTexture("_BaseMap").name + " ";
if (m.HasProperty("_MainTex") && m.GetTexture("_MainTex") != null) tex += "MainTex=" + m.GetTexture("_MainTex").name + " ";
texMats.Add(string.Format(" {0,-22} x{1,-3} sh={2,-42} {3}", m.name, kv.Value,
m.shader != null ? m.shader.name : "?", tex.Length > 0 ? tex : "<단색>"));
}
var lights = UnityEngine.Object.FindObjectsByType<UnityEngine.Light>(
UnityEngine.FindObjectsInactive.Exclude, UnityEngine.FindObjectsSortMode.None);
var cams = UnityEngine.Object.FindObjectsByType<UnityEngine.Camera>(
UnityEngine.FindObjectsInactive.Exclude, UnityEngine.FindObjectsSortMode.None);
var vols = UnityEngine.Object.FindObjectsByType<UnityEngine.Rendering.Volume>(
UnityEngine.FindObjectsInactive.Exclude, UnityEngine.FindObjectsSortMode.None);
sb.AppendLine("===== " + label + " =====");
sb.AppendLine(string.Format(" 렌더러 {0} (Mesh {1} / Skinned {2} / Particle {3}) · 머티리얼 슬롯 {4} · 고유 머티리얼 {5} · 삼각형 {6:N0}",
rends.Length, nMeshRend, nSkinned, nPart, slots, mats.Count, tris));
sb.AppendLine(" 셰이더별 슬롯:");
foreach (var kv in shaders) sb.AppendLine(string.Format(" {0,-46} x{1}", kv.Key, kv.Value));
sb.AppendLine(" 머티리얼 전수:");
texMats.Sort();
for (int i = 0; i < texMats.Count; i++) sb.AppendLine(texMats[i]);
sb.AppendLine(string.Format(" 라이트 {0}:", lights.Length));
for (int i = 0; i < lights.Length; i++)
sb.AppendLine(string.Format(" {0,-18} type={1} color={2} I={3} shadows={4} rot={5} urpData={6}",
lights[i].name, lights[i].type, lights[i].color.ToString("F4"),
lights[i].intensity, lights[i].shadows, lights[i].transform.rotation.eulerAngles.ToString("F3"),
lights[i].GetComponent<UnityEngine.Rendering.Universal.UniversalAdditionalLightData>() != null));
sb.AppendLine(string.Format(" 카메라 {0}:", cams.Length));
for (int i = 0; i < cams.Length; i++)
{
var c = cams[i];
var acd = c.GetComponent<UnityEngine.Rendering.Universal.UniversalAdditionalCameraData>();
sb.AppendLine(string.Format(" {0,-18} ortho={1} size={2} fov={3} near={4} far={5} clear={6} bg={7} pos={8} euler={9} urpData={10} post={11}",
c.name, c.orthographic, c.orthographicSize, c.fieldOfView, c.nearClipPlane, c.farClipPlane, c.clearFlags,
c.backgroundColor, c.transform.position.ToString("F3"), c.transform.rotation.eulerAngles.ToString("F3"),
acd != null, acd != null ? acd.renderPostProcessing.ToString() : "-"));
}
sb.AppendLine(string.Format(" Volume {0} · Terrain {1}", vols.Length,
UnityEngine.Terrain.activeTerrain != null ? UnityEngine.Terrain.activeTerrain.name : "<없음>"));
sb.AppendLine(string.Format(" RenderSettings: fog={0} ambMode={1} ambSky={2} ambEq={3} ambGnd={4} ambI={5} skybox={6} reflMode={7} reflI={8} sun={9}",
UnityEngine.RenderSettings.fog, UnityEngine.RenderSettings.ambientMode,
UnityEngine.RenderSettings.ambientSkyColor, UnityEngine.RenderSettings.ambientEquatorColor,
UnityEngine.RenderSettings.ambientGroundColor, UnityEngine.RenderSettings.ambientIntensity,
UnityEngine.RenderSettings.skybox != null ? UnityEngine.RenderSettings.skybox.name : "<없음>",
UnityEngine.RenderSettings.defaultReflectionMode, UnityEngine.RenderSettings.reflectionIntensity,
UnityEngine.RenderSettings.sun != null ? UnityEngine.RenderSettings.sun.name : "<없음>"));
}
public const string Dir = "Screenshots_WL/WL816a/";
public static void ShotLevel01()
{
UnityEditor.SceneManagement.EditorSceneManager.OpenScene(
"Assets/FarmingIsland/Scenes/Level01.unity", UnityEditor.SceneManagement.OpenSceneMode.Single);
Shot(Dir + "a_orig_level01.png", "MainCamera", 1080, 1920);
}
public static void ShotDemo()
{
UnityEditor.SceneManagement.EditorSceneManager.OpenScene(
"Assets/3DPixelArtEnvironment/Demo/Demo.unity", UnityEditor.SceneManagement.OpenSceneMode.Single);
Shot(Dir + "x_demo.png", "Main Camera", 1080, 1920);
}
// ── 에디트 모드 오프스크린 캡처 (UI 캔버스가 안 끼어든다) ───────────
/// <summary>현재 열린 씬의 카메라로 오프스크린 렌더 → PNG. 인자: 저장경로, 카메라이름(비우면 첫 카메라), w, h</summary>
public static void Shot(string savePath, string camName, int w, int h)
{
var cams = UnityEngine.Object.FindObjectsByType<UnityEngine.Camera>(
UnityEngine.FindObjectsInactive.Exclude, UnityEngine.FindObjectsSortMode.None);
UnityEngine.Camera cam = null;
for (int i = 0; i < cams.Length; i++) if (string.IsNullOrEmpty(camName) || cams[i].name == camName) { cam = cams[i]; break; }
if (cam == null) { UnityEngine.Debug.Log("[WL816a] 카메라 없음"); return; }
ShotFrom(cam, savePath, w, h);
}
public static void ShotFrom(UnityEngine.Camera cam, string savePath, int w, int h)
{
var rt = new UnityEngine.RenderTexture(w, h, 24, UnityEngine.RenderTextureFormat.ARGB32,
UnityEngine.RenderTextureReadWrite.sRGB);
rt.antiAliasing = 1;
var prevT = cam.targetTexture; var prevA = UnityEngine.RenderTexture.active;
cam.targetTexture = rt;
cam.Render();
UnityEngine.RenderTexture.active = rt;
var tex = new UnityEngine.Texture2D(w, h, UnityEngine.TextureFormat.RGB24, false);
tex.ReadPixels(new UnityEngine.Rect(0, 0, w, h), 0, 0);
tex.Apply();
UnityEngine.RenderTexture.active = prevA;
cam.targetTexture = prevT;
var bytes = UnityEngine.ImageConversion.EncodeToPNG(tex);
var dir = System.IO.Path.GetDirectoryName(savePath);
if (!System.IO.Directory.Exists(dir)) System.IO.Directory.CreateDirectory(dir);
System.IO.File.WriteAllBytes(savePath, bytes);
UnityEngine.Object.DestroyImmediate(tex);
UnityEngine.Object.DestroyImmediate(rt);
UnityEngine.Debug.Log("[WL816a] 캡처 " + savePath + " (" + w + "x" + h + ")");
}
}