// WL-815c 보유 에셋 실측 — 장벽 「보이기」 후보 (임시 · 커밋 대상) // unity command run_script --file AgentScripts/WL815c_Survey.cs --entry WL815c_Survey.Run --project-path E:\NerdNavis\WL_wt\gameplay2 public static class WL815c_Survey { static System.Text.StringBuilder s_sb; static void L(string s) { s_sb.AppendLine(s); UnityEngine.Debug.Log(s); } public static string Run() { s_sb = new System.Text.StringBuilder(); L("WL-815c 장벽 보이기 후보 실측 · " + System.DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss")); L(""); L("── ⓐ 링 후보 (Hovl) ─────────────────────────────────────────────"); string[] rings = { "Assets/ResWork/VFX/Hovl Studio/Map track markers VFX/Prefabs/Marker 3 Zone Loop.prefab", "Assets/ResWork/VFX/Hovl Studio/Map track markers VFX/Prefabs/Marker 5 Circle Loop.prefab", "Assets/ResWork/VFX/Hovl Studio/Map track markers VFX/Prefabs/Marker 7 Danger zone Loop.prefab", "Assets/ResWork/VFX/Hovl Studio/Map track markers VFX/Prefabs/Marker 8 Safe zone Loop.prefab", "Assets/ResWork/VFX/Hovl Studio/Map track markers VFX/Prefabs/Marker 4 Pillar Loop.prefab", "Assets/ResWork/VFX/Hovl Studio/Magic circles/Prefabs/Loop version/Magic circle 1 loop.prefab", "Assets/ResWork/VFX/Hovl Studio/Magic circles/Prefabs/Loop version/Magic circle 3 loop.prefab", "Assets/ResWork/VFX/Hovl Studio/Magic circles/Prefabs/Loop version/Magic circle 5 loop.prefab", }; for (int i = 0; i < rings.Length; i++) Measure(rings[i]); L(""); L("── ⓑ 프롭 후보 (울타리 · 바위 · 기둥) ───────────────────────────"); string[] props = { "Assets/ResWork/LowPolyFantasyVillage_URP/Prefabs/Props/Fence_01.prefab", "Assets/ResWork/LowPolyFantasyVillage_URP/Prefabs/Props/Fence_02.prefab", "Assets/ResWork/LowPolyFantasyVillage_URP/Prefabs/Props/FenceBig_01.prefab", "Assets/ResWork/LowPolyFantasyVillage_URP/Prefabs/Props/FenceBig_02.prefab", "Assets/LowPolyFantasyArena/Prefabs/FenceBig_01.prefab", "Assets/LowPolyFantasyArena/Prefabs/FenceBig_02.prefab", "Assets/ResWork/Aligned Games/Polygonal Woodlands Nature Asset Package/Models/Fence1/fence_1.prefab", "Assets/ResWork/Aligned Games/Polygonal Woodlands Nature Asset Package/Models/Fence2/fence_2.prefab", "Assets/3DPixelArtEnvironment/Prefabs/Stone_1.prefab", "Assets/3DPixelArtEnvironment/Prefabs/Stone_2.prefab", "Assets/3DPixelArtEnvironment/Prefabs/Slab.prefab", "Assets/3DPixelArtEnvironment/Prefabs/Arch_Small.prefab", "Assets/3DPixelArtEnvironment/Prefabs/Light_Post.prefab", }; for (int i = 0; i < props.Length; i++) Measure(props[i]); L(""); L("── LMHPOLY 바위 (자연 번들) ────────────────────────────────────"); var rockGuids = UnityEditor.AssetDatabase.FindAssets("t:Prefab", new string[] { "Assets/LMHPOLY/Low Poly Nature Bundle/Rocks" }); int shown = 0; for (int i = 0; i < rockGuids.Length && shown < 10; i++) { string p = UnityEditor.AssetDatabase.GUIDToAssetPath(rockGuids[i]); if (p.Contains("/LOD/") || p.Contains("Fireplace") || p.Contains("ParticleSystem")) continue; if (!p.Contains("Rock")) continue; Measure(p); shown++; } L(" (Rocks 폴더 프리팹 총 " + rockGuids.Length + "개)"); L(""); L("── ⓒ 불꽃 후보 ────────────────────────────────────────────────"); string[] fires = { "Assets/LMHPOLY/Low Poly Nature Bundle/Rocks/Bonus Assets/Prefabs/ParticleSystem/Fire_Particles.prefab", "Assets/ResWork/VFX/Hovl Studio/Epic Toon VFX 2/Prefabs/Fire buff/Fire buff.prefab", "Assets/ResWork/ModularDungeon/Prefabs/SK_Flame.prefab", "Assets/ResWork/EricWang/GameVFX Collection Vol3/Prefabs/FX_Flameflow_floor.prefab", "Assets/ResWork/VFX/StylizedFantasyFxPack/Prefab/PS_Cast_Fire.prefab", "Assets/Res_Addr/Effect/Effect_Hit_Mob_HellfireFlames.prefab", }; for (int i = 0; i < fires.Length; i++) Measure(fires[i]); L(""); L("── 불꽃 추가 탐색(이름에 Fire/Flame · 파티클 보유 · 루프) ───────"); var guids = UnityEditor.AssetDatabase.FindAssets("t:Prefab", new string[] { "Assets/ResWork/VFX" }); int hits = 0; for (int i = 0; i < guids.Length && hits < 14; i++) { string p = UnityEditor.AssetDatabase.GUIDToAssetPath(guids[i]); string n = System.IO.Path.GetFileNameWithoutExtension(p).ToLowerInvariant(); if (!(n.Contains("fire") || n.Contains("flame") || n.Contains("torch") || n.Contains("burn"))) continue; var go = UnityEditor.AssetDatabase.LoadAssetAtPath(p); if (go == null) continue; var pss = go.GetComponentsInChildren(true); if (pss.Length == 0) continue; bool loop = false; for (int k = 0; k < pss.Length; k++) if (pss[k].main.loop) loop = true; if (!loop) continue; Measure(p); hits++; } string outFile = "AgentScripts/WL815c_SURVEY.txt"; System.IO.File.WriteAllText(outFile, s_sb.ToString()); return "survey done → " + outFile; } static void Measure(string path) { var go = UnityEditor.AssetDatabase.LoadAssetAtPath(path); if (go == null) { L(" [없음] " + path); return; } var inst = UnityEngine.Object.Instantiate(go); inst.transform.position = UnityEngine.Vector3.zero; inst.transform.rotation = UnityEngine.Quaternion.identity; inst.transform.localScale = UnityEngine.Vector3.one; var rends = inst.GetComponentsInChildren(true); bool has = false; UnityEngine.Bounds b = new UnityEngine.Bounds(UnityEngine.Vector3.zero, UnityEngine.Vector3.zero); int meshRend = 0, partRend = 0; long tris = 0; for (int i = 0; i < rends.Length; i++) { var mf = rends[i].GetComponent(); if (mf != null && mf.sharedMesh != null) { meshRend++; tris += mf.sharedMesh.triangles.Length / 3; if (!has) { b = rends[i].bounds; has = true; } else b.Encapsulate(rends[i].bounds); } else if (rends[i] is UnityEngine.ParticleSystemRenderer) partRend++; else if (!has) { b = rends[i].bounds; has = true; } else b.Encapsulate(rends[i].bounds); } var pss = inst.GetComponentsInChildren(true); int maxParticles = 0; float rate = 0f, shapeR = 0f, dur = 0f; bool loop = false; for (int i = 0; i < pss.Length; i++) { var m = pss[i].main; maxParticles += m.maxParticles; dur = UnityEngine.Mathf.Max(dur, m.duration); if (m.loop) loop = true; var e = pss[i].emission; if (e.enabled) rate += e.rateOverTime.constantMax; var sh = pss[i].shape; if (sh.enabled) shapeR = UnityEngine.Mathf.Max(shapeR, sh.radius * pss[i].transform.lossyScale.x); } // 실 파티클 수 추정 = maxParticles 상한, 실효 = rate × lifetime float lifeSum = 0f; for (int i = 0; i < pss.Length; i++) lifeSum = UnityEngine.Mathf.Max(lifeSum, pss[i].main.startLifetime.constantMax); int mats = 0; var seen = new System.Collections.Generic.HashSet(); for (int i = 0; i < rends.Length; i++) { var ms = rends[i].sharedMaterials; for (int k = 0; k < ms.Length; k++) if (ms[k] != null && seen.Add(ms[k].GetInstanceID())) mats++; } L(" " + System.IO.Path.GetFileNameWithoutExtension(path)); L(" 경로 " + path); L(" 렌더러 " + rends.Length + "(메시 " + meshRend + " · 파티클 " + partRend + ") · 머티리얼 " + mats + " · 삼각형 " + tris); if (has) L(" 바운즈 크기 " + b.size.ToString("F2") + " · 중심 " + b.center.ToString("F2") + " · 최대반경(XZ) " + (UnityEngine.Mathf.Max(b.extents.x, b.extents.z)).ToString("F2") + " m"); else L(" 바운즈: 없음(메시 0)"); if (pss.Length > 0) L(" 파티클시스템 " + pss.Length + " · maxParticles 합 " + maxParticles + " · rateOverTime 합 " + rate.ToString("F1") + "/s · 최대수명 " + lifeSum.ToString("F2") + " s · 정상상태 추정 " + (rate * lifeSum).ToString("F0") + " · duration " + dur.ToString("F2") + " · loop " + (loop ? "Y" : "N") + " · shape radius " + shapeR.ToString("F2")); UnityEngine.Object.DestroyImmediate(inst); } }