// WL_MapSwitch.cs — PD 지시 #772 : 시작 맵 전환 도구 // 목록 : unity command run_script --file AgentScripts/WL_MapSwitch.cs --entry WL_MapSwitch.List // 전환 : unity command run_script --file AgentScripts/WL_MapSwitch.cs --entry WL_MapSwitch.Set --args '["WL_Nature03"]' // 복귀 : ... --entry WL_MapSwitch.Set --args '["WL_Nature"]' // // 동작 = BattleMapConfig.json 의 n_MapID "-1" 행(= 게임 시작 시 InGameInfo.Load_Map(-1) 이 읽는 행)의 // s_Scene 값만 바꾼다. 다른 행·필드는 건드리지 않는다. // 백업 = 첫 변경 시 AgentScripts/staging/WL_Maps/out/BattleMapConfig.json.bak_yyyyMMdd_HHmm (Assets 밖) 을 남기고, // 매 변경마다 같은 폴더 MapSwitch_history.txt 에 기록한다. // 인코딩 = UTF-8 BOM · 1줄 minified 원본 포맷을 그대로 유지한다 (문자열 치환 방식). // // 🔴 신규 맵을 인게임 맵 선택 UI 에서 고를 수는 없다 (MapChoiceUI_WorldMap 이 MapID = 탭인덱스+1 하드코딩). // 본 도구가 그 대체 수단이다. using System; using System.Linq; using System.Text; using System.Text.RegularExpressions; using UnityEngine; #if UNITY_EDITOR using UnityEditor; #endif public static class WL_MapSwitch { const string Json = "Assets/ResWork/Table/Export/BattleMapConfig.json"; const string MapDir = "Assets/Res_Addr/Map"; const string SceneDir = "Assets/Scenes"; const string HistDir = "AgentScripts/staging/WL_Maps/out"; static string Abs(string rel) { return System.IO.Path.Combine(System.IO.Directory.GetCurrentDirectory(), rel.Replace('/', System.IO.Path.DirectorySeparatorChar)); } static string ReadJson() { return System.IO.File.ReadAllText(Abs(Json), new UTF8Encoding(true)); } static void WriteJson(string s) { System.IO.File.WriteAllText(Abs(Json), s, new UTF8Encoding(true)); } // -1 행 안의 s_Scene 값을 잡는 정규식 (행 경계 = 다음 '}' 까지) static readonly Regex RxStartRow = new Regex("\\{\\s*\"n_MapID\"\\s*:\\s*\"-1\"[^}]*\\}", RegexOptions.Compiled); public static object List() { var sb = new StringBuilder(); var t = ReadJson(); var m = RxStartRow.Match(t); var cur = "(못 찾음)"; if (m.Success) { var s = Regex.Match(m.Value, "\"s_Scene\"\\s*:\\s*\"([^\"]*)\""); if (s.Success) cur = s.Groups[1].Value; } sb.AppendLine("현재 시작 맵 (BattleMapConfig n_MapID=-1 · s_Scene) = " + cur); sb.AppendLine(); sb.AppendLine("전환 가능한 맵 (프리팹 · 씬 · NavMesh 3종이 모두 있는 것만):"); #if UNITY_EDITOR foreach (var g in AssetDatabase.FindAssets("t:Prefab", new[] { MapDir }).Select(AssetDatabase.GUIDToAssetPath).OrderBy(x => x)) { var name = System.IO.Path.GetFileNameWithoutExtension(g); bool sceneOk = System.IO.File.Exists(Abs(SceneDir + "/" + name + ".unity")); bool navOk = System.IO.File.Exists(Abs("Assets/WL/Settings/" + name + "_NavMesh.asset")); bool inBuild = EditorBuildSettings.scenes.Any(x => x.path.EndsWith("/" + name + ".unity") && x.enabled); sb.AppendLine(string.Format(" {0,-16} 씬 {1} · NavMesh {2} · BuildSettings {3} {4}", name, sceneOk ? "O" : "X", navOk ? "O" : "X", inBuild ? "O" : "X", (sceneOk && inBuild) ? (name == cur ? " ← 현재" : "") : " (전환 불가)")); } #endif return sb.ToString(); } public static object Set(string sceneName) { if (string.IsNullOrEmpty(sceneName)) return "sceneName 이 비었다"; var scenePath = SceneDir + "/" + sceneName + ".unity"; if (!System.IO.File.Exists(Abs(scenePath))) return "씬이 없다: " + scenePath; #if UNITY_EDITOR if (!EditorBuildSettings.scenes.Any(x => x.path == scenePath && x.enabled)) return "EditorBuildSettings 에 등록(enabled)되어 있지 않다: " + scenePath; #endif var t = ReadJson(); var m = RxStartRow.Match(t); if (!m.Success) return "BattleMapConfig 에서 n_MapID=-1 행을 못 찾았다"; var row = m.Value; var sm = Regex.Match(row, "\"s_Scene\"\\s*:\\s*\"([^\"]*)\""); if (!sm.Success) return "-1 행에 s_Scene 이 없다"; var before = sm.Groups[1].Value; if (before == sceneName) return "이미 " + sceneName + " 이다 (변경 없음)"; // 백업 (첫 1회) — Assets 밖에 둔다 (Assets 안에 두면 Unity 가 에셋으로 임포트한다) var bakDir = Abs(HistDir); System.IO.Directory.CreateDirectory(bakDir); var bak = System.IO.Path.Combine(bakDir, "BattleMapConfig.json.bak_" + DateTime.Now.ToString("yyyyMMdd_HHmm")); if (!System.IO.File.Exists(bak)) System.IO.File.Copy(Abs(Json), bak); var newRow = row.Substring(0, sm.Groups[1].Index) + sceneName + row.Substring(sm.Groups[1].Index + before.Length); var outText = t.Substring(0, m.Index) + newRow + t.Substring(m.Index + m.Length); WriteJson(outText); System.IO.Directory.CreateDirectory(Abs(HistDir)); System.IO.File.AppendAllText(Abs(HistDir + "/MapSwitch_history.txt"), string.Format("{0} {1} -> {2}\n", DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"), before, sceneName), new UTF8Encoding(true)); #if UNITY_EDITOR AssetDatabase.ImportAsset(Json, ImportAssetOptions.ForceUpdate); AssetDatabase.SaveAssets(); #endif return string.Format("시작 맵 {0} -> {1} (백업 {1}: {2})", before, sceneName, System.IO.Path.GetFileName(bak)); } }