using System; using System.Collections; using System.Collections.Generic; using System.Data.Common; using System.IO; using System.Linq; using System.Text.RegularExpressions; using UnityEditor; using UnityEngine; using UnityEngine.UI; ///最上面 ///功能:扫描地图、打开地图、关闭地图、放弃设置 public class UIMapPanel : MonoBehaviour { public ToggleGroup mapEditorGroup; public Dropdown dropMap; private bool _saving; // Start is called before the first frame update void Start() { _saving = false; dropMap.onValueChanged.AddListener(delegate { if (dropMap.options.Count > 0) { int mapId = Convert.ToInt32(dropMap.options[dropMap.value].text); UICellInfo.Instance.ShowMapWidthAndHeight(mapId); } }); } void OnDataLoaded() { // 获取所有地图文件夹 string mapsDirectory = Path.Combine(Application.dataPath, "GameAssets", "Maps"); if (!Directory.Exists(mapsDirectory)) { Debug.LogError($"Maps directory not found: {mapsDirectory}"); return; } MapManager.Instance.allMaps.Clear(); string[] mapFolders = Directory.GetDirectories(mapsDirectory); // 按 mapId 数字部分升序排序 var sortedMapFolders = mapFolders .OrderBy(folderPath => { string folderName = Path.GetFileName(folderPath); // 例如 "v1000" // 提取数字部分 var match = Regex.Match(folderName, @"\d+"); return match.Success ? int.Parse(match.Value) : int.MaxValue; }) .ToArray(); foreach (string folderPath in sortedMapFolders) { string[] pathSplit = folderPath.Split(Path.DirectorySeparatorChar); string mapId = pathSplit[pathSplit.Length - 1]; // 例如 "v1000" string textureDirectory = Path.Combine(folderPath, "Texture"); if (Directory.Exists(textureDirectory)) { string[] imageFiles = Directory.GetFiles(textureDirectory, "*.jpg"); int maxRow = 0; int maxCol = 0; string pattern = $@"r(\d+)_c(\d+)"; // 正则表达式:匹配 v1000_rXX_cYY Regex regex = new Regex(pattern); foreach (string filePath in imageFiles) { string fileName = Path.GetFileNameWithoutExtension(filePath); // 例如 "v1000_r11_c14" Match match = regex.Match(fileName); if (match.Success) { if (int.TryParse(match.Groups[1].Value, out int row) && int.TryParse(match.Groups[2].Value, out int col)) { maxRow = Mathf.Max(maxRow, row); maxCol = Mathf.Max(maxCol, col); } } else { Debug.LogWarning($"Filename {fileName} does not match expected pattern: {pattern}"); } } MapManager.Instance.allMaps[mapId] = (maxCol, maxRow, imageFiles.Length); } else { Debug.LogWarning($"Texture directory not found for map {mapId}: {textureDirectory}"); } } } /// /// 重命名图片格式从 map_x 到 v{mapId}_rx_cx 格式(包含重复检查) /// public void ReNamePicFormat() { int mapId = Convert.ToInt32(dropMap.options[dropMap.value].text); int width = UICellInfo.Instance.CustomMapWidth; // 地图宽度(列数) string mapsDirectory = Path.Combine(Application.dataPath, "GameAssets", "Maps", $"{mapId}", "Texture"); if (!Directory.Exists(mapsDirectory)) { Debug.LogError($"Maps directory not found: {mapsDirectory}"); return; } // 获取所有jpg文件 string[] imageFiles = Directory.GetFiles(mapsDirectory, "*.jpg"); int totalFiles = imageFiles.Length; if (totalFiles == 0) { UIWindow.Instance.ShowMessage($"No jpg files found in directory: {mapsDirectory}"); return; } // 检查是否已经是目标命名格式 if (IsAlreadyRenamed(imageFiles, mapId)) { UIWindow.Instance.ShowMessage($"文件夹 {mapId} 已经是目标命名格式,跳过重命名"); return; } // 检查是否混合格式(部分已重命名,部分未重命名) if (IsMixedFormat(imageFiles, mapId)) { UIWindow.Instance.ShowMessage($"文件夹 {mapId} 包含混合格式的文件,请先清理文件夹"); return; } // 按数字排序map_格式的文件 var mapFiles = imageFiles .Where(file => Path.GetFileNameWithoutExtension(file).StartsWith("map_")) .OrderBy(file => { string fileName = Path.GetFileNameWithoutExtension(file); if (int.TryParse(fileName.Substring(4), out int number)) { return number; } return int.MaxValue; }) .ToArray(); if (mapFiles.Length == 0) { UIWindow.Instance.ShowMessage($"没有找到map_格式的文件,但也不是目标格式"); return; } // 计算行数 int height = Mathf.CeilToInt((float)mapFiles.Length / width); UIWindow.Instance.ShowMessage($"Renaming {mapFiles.Length} files with grid size: {width}x{height}"); int renamedCount = 0; int errorCount = 0; // 执行重命名操作 for (int index = 0; index < mapFiles.Length; index++) { string oldFilePath = mapFiles[index]; string fileName = Path.GetFileNameWithoutExtension(oldFilePath); string fileExtension = Path.GetExtension(oldFilePath); try { // 计算行列位置(从1开始) int row = (index / width) + 1; int col = (index % width) + 1; // 生成新文件名(使用地图ID) string newFileName = $"r{row}_c{col}"; string newFilePath = Path.Combine(mapsDirectory, newFileName + fileExtension); // 重命名文件 File.Move(oldFilePath, newFilePath); renamedCount++; Debug.Log($"Renamed: {fileName} -> {newFileName}"); } catch (Exception ex) { errorCount++; Debug.LogError($"Error renaming file {fileName}: {ex.Message}"); } } Debug.Log($"Rename completed. Success: {renamedCount}, Errors: {errorCount}"); // 刷新AssetDatabase #if UNITY_EDITOR UnityEditor.AssetDatabase.Refresh(); #endif OnDataLoaded(); } /// /// 检查是否已经是目标命名格式 /// private bool IsAlreadyRenamed(string[] imageFiles, int mapId) { // 目标格式的正则表达式:v{mapId}_r数字_c数字 string pattern = $"^r\\d+_c\\d+$"; var regex = new System.Text.RegularExpressions.Regex(pattern); foreach (string filePath in imageFiles) { string fileName = Path.GetFileNameWithoutExtension(filePath); // 如果发现任何非目标格式的文件,就不是已重命名状态 if (!regex.IsMatch(fileName) && !fileName.StartsWith("map_")) { return false; } } // 检查是否至少有一个目标格式的文件 bool hasTargetFormat = imageFiles.Any(file => regex.IsMatch(Path.GetFileNameWithoutExtension(file))); return hasTargetFormat; } /// /// 检查是否混合格式(既有目标格式又有map_格式) /// private bool IsMixedFormat(string[] imageFiles, int mapId) { bool hasMapFormat = false; bool hasTargetFormat = false; string pattern = $"^r\\d+_c\\d+$"; var regex = new System.Text.RegularExpressions.Regex(pattern); foreach (string filePath in imageFiles) { string fileName = Path.GetFileNameWithoutExtension(filePath); if (fileName.StartsWith("map_")) { hasMapFormat = true; } else if (regex.IsMatch(fileName)) { hasTargetFormat = true; } // 如果同时存在两种格式,就是混合状态 if (hasMapFormat && hasTargetFormat) { return true; } } return false; } public void ExportMap() { MapManager.Instance.SaveAtlasToFile(); } public void ScanMap() { MapManager.Instance.allMaps.Clear(); OnDataLoaded(); dropMap.options.Clear(); foreach (var map in MapManager.Instance.allMaps) { Dropdown.OptionData od = new Dropdown.OptionData(); od.text = map.Key; dropMap.options.Add(od); } dropMap.value = 1; dropMap.value = 0; //为了默认选中第一项 } public void OpenMap() { if(dropMap.options.Count == 0) { UIWindow.Instance.ShowMessage("请先扫描地图"); return; } if(MapManager.Instance._curOpenMapId > 0) { UIWindow.Instance.ShowMessage("请先关闭已有地图"); return; } int mapId = Convert.ToInt32(dropMap.options[dropMap.value].text); MapManager.Instance._curOpenMapId = mapId; MapManager.Instance.LoadMapRegionSprites(mapId); MapManager.Instance.LoadMapObs(mapId); UIWindow.Instance.uiEditMapConfig.LoadMapConfig(mapId); UIWindow.Instance.uiMonstersPanel.LoadMonsterConfig(mapId); UIWindow.Instance.uiNpcsPanel.LoadNpcsConfig(mapId); UIWindow.Instance.uiTriggersPanel.LoadTriggersConfig(mapId); UIWindow.Instance.uiFuBensPanel.LoadFuBenConfig(mapId); UIWindow.Instance.uiJuBaosPanel.LoadJuBaoConfig(mapId); //如果没有配置,需要创建阻隔点 if (MapManager.Instance.map == null) { MapManager.Instance.CreateObs(mapId); } UICellInfo.Instance.ShowMapCellInfo(); } public void CloseMap() { MapManager.Instance.CloseMap(); MapManager.Instance._curOpenMapId = -1; foreach (var toggle in mapEditorGroup.ActiveToggles()) { toggle.isOn = false; } } public bool HasMap(string mapId) { return MapManager.Instance.allMaps.ContainsKey(mapId); } private void Update() { if (Input.GetKey(KeyCode.LeftControl) && Input.GetKey(KeyCode.S)) { if (_saving) return; SaveAll(); } } public void SaveAll() { _saving = true; Debug.Log("正在保存所有数据..."); MapManager.Instance.SaveRegionXML(); MapManager.Instance.SaveMapObs(); UIWindow.Instance.uiEditMapConfig.SaveMapConfig(); UIWindow.Instance.uiMonstersPanel.SaveMonsterConfig(); UIWindow.Instance.uiNpcsPanel.SaveNpcsConfig(); UIWindow.Instance.uiTriggersPanel.SaveTriggersConfig(); UIWindow.Instance.uiJuBaosPanel.SaveJuBaoConfig(); UIWindow.Instance.uiFuBensPanel.SaveFuBenConfig(); UIWindow.Instance.ShowMessage("保存成功"); _saving = false; #if UNITY_EDITOR AssetDatabase.Refresh(); #endif } }