// WL-816f §2 — 데모 바닥 vs 우리 바닥 실측(에디트 모드 · 데모 씬 Play 안 함) // ① 풀 메시의 월드 크기 ② 격자 간격 ③ 풀 머티리얼 색 ④ 바닥 머티리얼 색 public static class WL816f_Ground { public static void Run() { var sb = new System.Text.StringBuilder(); // ── 데모 ──────────────────────────────────────────────────── UnityEditor.SceneManagement.EditorSceneManager.OpenScene( "Assets/3DPixelArtEnvironment/Demo/Demo.unity", UnityEditor.SceneManagement.OpenSceneMode.Single); sb.AppendLine("=== 데모 (Demo.unity) ==="); var tibs = UnityEngine.Object.FindObjectsByType( UnityEngine.FindObjectsInactive.Include, UnityEngine.FindObjectsSortMode.None); foreach (var t in tibs) { sb.AppendLine("TIB " + t.name + " lossyScale=" + t.transform.lossyScale.ToString("F3") + " posVar=" + t.PositionVariance + " scaleVar=" + t.ScaleVariance); var terr = t.GetComponent(); if (terr != null) sb.AppendLine(" terrain size=" + terr.terrainData.size.ToString("F1") + " alphamapTex=" + terr.terrainData.alphamapTextureCount + " mat=" + (terr.materialTemplate ? terr.materialTemplate.name + " (" + terr.materialTemplate.shader.name + ")" : "없음")); Layer(sb, "1층", t.FirstLayer, t.transform.lossyScale); Layer(sb, "2층", t.SecondLayer, t.transform.lossyScale); Layer(sb, "3층", t.ThirdLayer, t.transform.lossyScale); Layer(sb, "4층", t.FourthLayer, t.transform.lossyScale); if (terr != null && terr.materialTemplate != null) MatDump(sb, " 지형mat ", terr.materialTemplate); } // 데모 지형 스플랫 — 1층(풀)이 차지하는 면적 비율 foreach (var t in tibs) { var terr = t.GetComponent(); if (terr == null || terr.terrainData.alphamapTextureCount == 0) continue; var tex = terr.terrainData.alphamapTextures[0]; var px = tex.GetPixels(); int[] cnt = new int[4]; for (int i = 0; i < px.Length; i++) { float[] v = { px[i].r, px[i].g, px[i].b, px[i].a }; int bi = 0; for (int k = 1; k < 4; k++) if (v[k] > v[bi]) bi = k; cnt[bi]++; } sb.AppendLine(" 스플랫 지배비율(" + tex.width + "x" + tex.height + "): 1층 " + (100f * cnt[0] / px.Length).ToString("F1") + "% · 2층 " + (100f * cnt[1] / px.Length).ToString("F1") + "% · 3층 " + (100f * cnt[2] / px.Length).ToString("F1") + "% · 4층 " + (100f * cnt[3] / px.Length).ToString("F1") + "%"); } // ── 우리 ──────────────────────────────────────────────────── sb.AppendLine(); sb.AppendLine("=== 우리 (WLIslandLookSettings) ==="); var cfg = UnityEditor.AssetDatabase.LoadAssetAtPath( "Assets/WL/Look/Farm/Resources/WL/WLIslandLookSettings.asset"); sb.AppendLine("posVar=" + cfg.positionVariance + " scaleVar=" + cfg.scaleVariance + " edgeInset=" + cfg.edgeInset); for (int i = 0; i < cfg.scatter.Length; i++) { var s = cfg.scatter[i]; var b = s.mesh != null ? s.mesh.bounds.size : UnityEngine.Vector3.zero; sb.AppendLine(" [" + s.label + "] en=" + s.enabled_ + " mesh=" + (s.mesh ? s.mesh.name : "없음") + " bounds=" + b.ToString("F3") + " scale=" + s.scale + " → 월드 " + (b * s.scale).ToString("F3") + " · prob=" + s.probability + " density=" + s.density + "(=" + (s.density * s.density).ToString("F2") + "개/㎡ · 격자 " + (1f / s.density).ToString("F3") + "m)" + " mat=" + (s.material ? s.material.name : "없음")); if (s.material != null) MatDump(sb, " ", s.material); } sb.AppendLine("islandTopMaterial = " + (cfg.islandTopMaterial ? cfg.islandTopMaterial.name : "없음")); if (cfg.islandTopMaterial != null) MatDump(sb, " ", cfg.islandTopMaterial); for (int i = 0; i < cfg.materialRemap.Length; i++) { var e = cfg.materialRemap[i]; sb.AppendLine(" remap en=" + e.enabled_ + " " + (e.from ? e.from.name : "-") + " → " + (e.to ? e.to.name : "-") + (e.to != null && e.to.HasProperty("_BaseMap") && e.to.GetTexture("_BaseMap") != null ? " 🔴텍스처 " + e.to.GetTexture("_BaseMap").name : " (텍스처 없음)")); } System.IO.File.WriteAllText("AgentScripts/WL816f_GROUND.txt", sb.ToString()); UnityEngine.Debug.Log(sb.ToString()); } static void Layer(System.Text.StringBuilder sb, string name, Environment.Instancing.TerrainInstancesBehaviour.TerrainInstancingInput inp, UnityEngine.Vector3 lossy) { if (inp == null || inp.Settings == null || inp.Settings.Length == 0) { sb.AppendLine(" " + name + " (없음)"); return; } sb.AppendLine(" " + name + " Density=" + inp.Density + " (=" + (inp.Density * inp.Density).ToString("F2") + "개/㎡ · 격자 " + (1f / inp.Density).ToString("F3") + "m)"); foreach (var s in inp.Settings) { var b = s.Mesh != null ? s.Mesh.bounds.size : UnityEngine.Vector3.zero; var w = new UnityEngine.Vector3(b.x * s.Scale * lossy.x, b.y * s.Scale * lossy.y, b.z * s.Scale * lossy.z); sb.AppendLine(" mesh=" + (s.Mesh ? s.Mesh.name + "(tri " + (s.Mesh.triangles.Length / 3) + ")" : "없음") + " bounds=" + b.ToString("F3") + " Scale=" + s.Scale + " → 월드 " + w.ToString("F3") + " prob=" + s.Probability + " nOff=" + s.NormalOffset + " mat=" + (s.Material ? s.Material.name : "없음")); if (s.Material != null) MatDump(sb, " ", s.Material); } } static void MatDump(System.Text.StringBuilder sb, string pad, UnityEngine.Material m) { string[] cols = { "_DiffuseColor", "_ShadowDiffuseColor", "_BaseColor", "_Color", "_TopColor", "_BottomColor", "_TipColor" }; string[] flts = { "_Shades", "_Brightness", "_MinimumDarkness", "_AmbientStrength", "_Cull", "_WindStrength", "_WindDensity" }; var s = pad + "shader=" + m.shader.name; foreach (var c in cols) if (m.HasProperty(c)) s += " " + c + "=" + Hex(m.GetColor(c)); foreach (var f in flts) if (m.HasProperty(f)) s += " " + f + "=" + m.GetFloat(f).ToString("F3"); if (m.HasProperty("_BaseMap")) s += " _BaseMap=" + (m.GetTexture("_BaseMap") ? m.GetTexture("_BaseMap").name : "없음"); if (m.HasProperty("_ShadowBaseMap")) s += " _ShadowBaseMap=" + (m.GetTexture("_ShadowBaseMap") ? m.GetTexture("_ShadowBaseMap").name : "없음"); sb.AppendLine(s); } static string Hex(UnityEngine.Color c) { return "(" + c.r.ToString("F3") + "," + c.g.ToString("F3") + "," + c.b.ToString("F3") + ")#" + UnityEngine.ColorUtility.ToHtmlStringRGB(c); } }