104 lines
5.5 KiB
C#
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));
|
||
|
|
}
|
||
|
|
}
|