// WL-816e 실측 프로브 — ① 데모 풀밭이 정확히 무엇인가 ② 섬 타일의 윗면·제외 대상 // 원본 씬은 열기만 하고 저장하지 않는다. public static class WL816e_Probe { public static void Run() { var sb = new System.Text.StringBuilder(); Demo(sb); Island(sb); UnityEngine.Debug.Log(sb.ToString()); } // ── ① 데모 풀밭 ──────────────────────────────────────────────────── public static void Demo(System.Text.StringBuilder sb) { UnityEditor.SceneManagement.EditorSceneManager.OpenScene( "Assets/3DPixelArtEnvironment/Demo/Demo.unity", UnityEditor.SceneManagement.OpenSceneMode.Single); sb.AppendLine("===== A. DEMO GRASS ====="); var behaviours = UnityEngine.Object.FindObjectsByType( UnityEngine.FindObjectsInactive.Include, UnityEngine.FindObjectsSortMode.None); sb.AppendLine("InstancesBehaviour 개수 = " + behaviours.Length); for (int i = 0; i < behaviours.Length; i++) { var b = behaviours[i]; sb.AppendLine("--- [" + i + "] " + b.name + " (" + b.GetType().Name + ") active=" + b.gameObject.activeInHierarchy + " enabled=" + b.enabled + " pos=" + b.transform.position.ToString("F3")); var ti = b as Environment.Instancing.TerrainInstancesBehaviour; if (ti == null) continue; sb.AppendLine(" PositionVariance=" + ti.PositionVariance + " ScaleVariance=" + ti.ScaleVariance); var terr = b.GetComponent(); if (terr != null) { var td = terr.terrainData; sb.AppendLine(" Terrain size=" + td.size.ToString("F3") + " alphamapTextureCount=" + td.alphamapTextureCount + " alphamapRes=" + td.alphamapResolution + " heightmapRes=" + td.heightmapResolution + " bounds=" + td.bounds.ToString() + " drawTreesAndFoliage=" + terr.drawTreesAndFoliage + " terrainMat=" + (terr.materialTemplate == null ? "null" : terr.materialTemplate.name + "/" + terr.materialTemplate.shader.name)); // 지형 지면의 실제 높낮이 float minH = 9999f, maxH = -9999f; for (int x = 0; x <= 20; x++) for (int z = 0; z <= 20; z++) { float h = td.GetInterpolatedHeight(x / 20f, z / 20f); if (h < minH) minH = h; if (h > maxH) maxH = h; } sb.AppendLine(" 지형 높이 min=" + minH.ToString("F3") + " max=" + maxH.ToString("F3")); } var inputs = new Environment.Instancing.TerrainInstancesBehaviour.TerrainInstancingInput[] { ti.FirstLayer, ti.SecondLayer, ti.ThirdLayer, ti.FourthLayer }; string[] names = { "FirstLayer", "SecondLayer", "ThirdLayer", "FourthLayer" }; for (int L = 0; L < inputs.Length; L++) { var inp = inputs[L]; if (inp == null) { sb.AppendLine(" " + names[L] + " = null"); continue; } int nset = inp.Settings == null ? 0 : inp.Settings.Length; sb.AppendLine(" " + names[L] + " Density=" + inp.Density + " (=> " + (inp.Density * inp.Density).ToString("F4") + " 개/㎡ · step " + (1f / inp.Density).ToString("F3") + "m) settings=" + nset); for (int s = 0; s < nset; s++) { var st = inp.Settings[s]; if (st == null) { sb.AppendLine(" [" + s + "] null"); continue; } long tris = 0; if (st.Mesh != null) for (int m = 0; m < st.Mesh.subMeshCount; m++) tris += st.Mesh.GetIndexCount(m) / 3; sb.AppendLine(" [" + s + "] mesh=" + (st.Mesh == null ? "null" : st.Mesh.name + " tris=" + tris + " bounds=" + st.Mesh.bounds.size.ToString("F4")) + " mat=" + (st.Material == null ? "null" : st.Material.name + "/" + st.Material.shader.name) + " Prob=" + st.Probability + " Scale=" + st.Scale + " NormalOffset=" + st.NormalOffset); } } } // 인스턴스 머티리얼 값 전수 string[] matPaths = { "Assets/3DPixelArtEnvironment/Materials/Instanced_Grass.mat", "Assets/3DPixelArtEnvironment/Materials/Instanced_Flower.mat", "Assets/3DPixelArtEnvironment/Materials/Instanced_Gravel.mat", "Assets/3DPixelArtEnvironment/Materials/Instanced_Leaves.mat", "Assets/3DPixelArtEnvironment/Materials/Terrain.mat", }; for (int i = 0; i < matPaths.Length; i++) { var m = UnityEditor.AssetDatabase.LoadAssetAtPath(matPaths[i]); if (m == null) { sb.AppendLine("MAT 없음: " + matPaths[i]); continue; } sb.AppendLine("MAT " + m.name + " shader=" + m.shader.name + " renderQueue=" + m.renderQueue + " keywords=[" + string.Join(",", m.shaderKeywords) + "]"); var sh = m.shader; int n = UnityEditor.ShaderUtil.GetPropertyCount(sh); for (int p = 0; p < n; p++) { string pn = UnityEditor.ShaderUtil.GetPropertyName(sh, p); var pt = UnityEditor.ShaderUtil.GetPropertyType(sh, p); string v; if (pt == UnityEditor.ShaderUtil.ShaderPropertyType.Color) v = m.GetColor(pn).ToString("F4"); else if (pt == UnityEditor.ShaderUtil.ShaderPropertyType.Vector) v = m.GetVector(pn).ToString("F4"); else if (pt == UnityEditor.ShaderUtil.ShaderPropertyType.TexEnv) { var t = m.GetTexture(pn); v = t == null ? "none" : t.name; } else v = m.GetFloat(pn).ToString("F4"); sb.Append(" " + pn + "=" + v + "\n"); } } } // ── ② 섬 ─────────────────────────────────────────────────────────── public static void Island(System.Text.StringBuilder sb) { UnityEditor.SceneManagement.EditorSceneManager.OpenScene( "Assets/FarmingIsland/Scenes/Level01.unity", UnityEditor.SceneManagement.OpenSceneMode.Single); sb.AppendLine("===== B. LEVEL01 ISLAND ====="); var mgr = UnityEngine.Object.FindFirstObjectByType(UnityEngine.FindObjectsInactive.Include); sb.AppendLine("IslandManager = " + (mgr == null ? "null" : mgr.name + " IslandSize=" + mgr.IslandSize)); var islands = UnityEngine.Object.FindObjectsByType( UnityEngine.FindObjectsInactive.Include, UnityEngine.FindObjectsSortMode.None); sb.AppendLine("Island 개수 = " + islands.Length); int unlocked = 0; for (int i = 0; i < islands.Length; i++) { var isl = islands[i]; if (isl.IsUnlocked) unlocked++; var mf = isl.GetComponent(); var mr = isl.GetComponent(); string meshInfo = "none"; if (mf != null && mf.sharedMesh != null) meshInfo = mf.sharedMesh.name + " bounds=" + mf.sharedMesh.bounds.ToString() + " tris=" + (mf.sharedMesh.GetIndexCount(0) / 3); string matInfo = mr == null ? "none" : (mr.sharedMaterial == null ? "null" : mr.sharedMaterial.name + "/" + mr.sharedMaterial.shader.name); sb.AppendLine(" [" + i + "] " + isl.name + " pos=" + isl.transform.position.ToString("F2") + " rotY=" + isl.transform.eulerAngles.y.ToString("F0") + " scale=" + isl.transform.localScale.ToString("F2") + " active=" + isl.gameObject.activeSelf + " Unlocked=" + isl.IsUnlocked + " Bridge=" + isl.IsBridge + " Road=" + isl.HasRoad + " mesh=" + meshInfo + " mat=" + matInfo + " children=" + isl.transform.childCount); if (i < 3) { for (int c = 0; c < isl.transform.childCount; c++) { var ch = isl.transform.GetChild(c); var cmr = ch.GetComponent(); var cmf = ch.GetComponent(); sb.AppendLine(" child[" + c + "] " + ch.name + " active=" + ch.gameObject.activeSelf + " localPos=" + ch.localPosition.ToString("F2") + " comps=" + Comps(ch.gameObject) + (cmf != null && cmf.sharedMesh != null ? " mesh=" + cmf.sharedMesh.name + " b=" + cmf.sharedMesh.bounds.ToString() : "") + (cmr != null && cmr.sharedMaterial != null ? " mat=" + cmr.sharedMaterial.name : "")); } } } sb.AppendLine("Unlocked island 수 = " + unlocked); // 섬 콜라이더(윗면 판정용) var isl0 = islands.Length > 0 ? islands[0] : null; if (isl0 != null) { var cols = isl0.GetComponentsInChildren(true); for (int c = 0; c < cols.Length; c++) sb.AppendLine(" ISL0 collider " + cols[c].GetType().Name + " on " + cols[c].name + " enabled=" + cols[c].enabled + " trigger=" + cols[c].isTrigger + " bounds=" + cols[c].bounds.ToString() + " layer=" + UnityEngine.LayerMask.LayerToName(cols[c].gameObject.layer)); } // 농사 타일 / 길 / 건물 var farms = UnityEngine.Object.FindObjectsByType(UnityEngine.FindObjectsInactive.Include, UnityEngine.FindObjectsSortMode.None); sb.AppendLine("Farm 개수 = " + farms.Length); for (int i = 0; i < farms.Length; i++) { var f = farms[i]; var soils = f.GetComponentsInChildren(true); var rends = f.GetComponentsInChildren(true); var b = new UnityEngine.Bounds(f.transform.position, UnityEngine.Vector3.zero); for (int r = 0; r < rends.Length; r++) b.Encapsulate(rends[r].bounds); sb.AppendLine(" Farm[" + i + "] " + f.name + " pos=" + f.transform.position.ToString("F2") + " soils=" + soils.Length + " rends=" + rends.Length + " worldBounds=" + b.ToString()); } var props = UnityEngine.Object.FindObjectsByType(UnityEngine.FindObjectsInactive.Include, UnityEngine.FindObjectsSortMode.None); int nprop = 0; var propTypes = new System.Collections.Generic.Dictionary(); for (int i = 0; i < props.Length; i++) { if (props[i] is CryingSnow.FarmingIsland.IProp) { nprop++; string t = props[i].GetType().Name; propTypes[t] = propTypes.TryGetValue(t, out int v) ? v + 1 : 1; } } sb.AppendLine("IProp 개수 = " + nprop); foreach (var kv in propTypes) sb.AppendLine(" " + kv.Key + " x" + kv.Value); // 레이어 목록 sb.AppendLine("--- 레이어 ---"); for (int i = 0; i < 32; i++) { string ln = UnityEngine.LayerMask.LayerToName(i); if (!string.IsNullOrEmpty(ln)) sb.Append(i + ":" + ln + " "); } sb.AppendLine(); } static string Comps(UnityEngine.GameObject go) { var cs = go.GetComponents(); var s = new System.Text.StringBuilder(); for (int i = 0; i < cs.Length; i++) { if (cs[i] == null) continue; s.Append(cs[i].GetType().Name); s.Append('|'); } return s.ToString(); } }