Project_WL/AgentScripts/WL_MapSwitch.cs

104 lines
5.5 KiB
C#

// 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));
}
}