// 발주서 WL-813t3 §1-3ⓐ — NavMesh 전역 에이전트 슬로프 변경 (Humanoid 45° → 30°) // // 보기 : unity command --project-path E:\NerdNavis\WL_wt\data run_script --file AgentScripts/WL813t3_Slope.cs --entry WL813t3_Slope.Show --timeout 300 // 적용 : … --entry WL813t3_Slope.Set30 // 되돌림 : … --entry WL813t3_Slope.Restore45 // // 🔴 슬로프는 프로젝트 전역값(ProjectSettings/NavMeshAreas.asset)이다. **이미 구워진 다른 맵 NavMesh 데이터는 // 바뀌지 않는다**(재베이크할 때만 영향). 이 프로젝트에서 재베이크하는 것은 WL_Nature 하나뿐이다. // 파일을 손으로 고치면 실행 중인 에디터의 메모리 값이 안 바뀌므로, 여기서는 Navigation 창과 같은 경로 // (`Unsupported.GetSerializedAssetInterfaceSingleton("NavMeshProjectSettings")` + SerializedObject)로 고친다. public static class WL813t3_Slope { public static string Show() { return Apply(-1f); } public static string Set30() { return Apply(30f); } public static string Restore45() { return Apply(45f); } static string Apply(float slope) { var sb = new System.Text.StringBuilder(); var singleton = UnityEditor.Unsupported.GetSerializedAssetInterfaceSingleton("NavMeshProjectSettings"); if (singleton == null) { sb.AppendLine("[에러] NavMeshProjectSettings 싱글턴을 못 얻었다"); return sb.ToString(); } var so = new UnityEditor.SerializedObject(singleton); var arr = so.FindProperty("m_Settings"); var names = so.FindProperty("m_SettingNames"); if (arr == null) { sb.AppendLine("[에러] m_Settings 프로퍼티 없음"); return sb.ToString(); } sb.AppendLine("에이전트 타입 " + arr.arraySize + "개"); for (int i = 0; i < arr.arraySize; i++) { var e = arr.GetArrayElementAtIndex(i); var id = e.FindPropertyRelative("agentTypeID"); var r = e.FindPropertyRelative("agentRadius"); var h = e.FindPropertyRelative("agentHeight"); var sl = e.FindPropertyRelative("agentSlope"); var cl = e.FindPropertyRelative("agentClimb"); string nm = (names != null && i < names.arraySize) ? names.GetArrayElementAtIndex(i).stringValue : "?"; sb.AppendLine(" [" + i + "] " + nm + " · agentTypeID " + (id != null ? id.intValue.ToString() : "?") + " · radius " + (r != null ? r.floatValue.ToString("F3") : "?") + " · height " + (h != null ? h.floatValue.ToString("F3") : "?") + " · **slope " + (sl != null ? sl.floatValue.ToString("F2") : "?") + "**" + " · climb " + (cl != null ? cl.floatValue.ToString("F3") : "?")); if (slope > 0f && id != null && id.intValue == 0 && sl != null) { float old = sl.floatValue; sl.floatValue = slope; sb.AppendLine(" → Humanoid(agentTypeID 0) slope " + old.ToString("F2") + " → " + slope.ToString("F2") + " 로 변경"); } } if (slope > 0f) { so.ApplyModifiedPropertiesWithoutUndo(); UnityEditor.AssetDatabase.SaveAssets(); UnityEditor.EditorUtility.SetDirty(singleton); UnityEditor.AssetDatabase.SaveAssets(); var check = UnityEngine.AI.NavMesh.GetSettingsByID(0); sb.AppendLine("저장 후 NavMesh.GetSettingsByID(0) 실측 — radius " + check.agentRadius + " · height " + check.agentHeight + " · **slope " + check.agentSlope + "** · climb " + check.agentClimb + " · minRegionArea " + check.minRegionArea + " · voxel " + check.voxelSize.ToString("F5")); } else { var check = UnityEngine.AI.NavMesh.GetSettingsByID(0); sb.AppendLine("현재 NavMesh.GetSettingsByID(0) — slope " + check.agentSlope + " · climb " + check.agentClimb); } UnityEngine.Debug.Log("[WL813t3_Slope]\n" + sb.ToString()); return sb.ToString(); } }