using TGS; using Gameplay; using PhxhSDK.AOT; using System.Linq; using UnityEngine; using File = System.IO.File; using System.Collections.Generic; #if UNITY_EDITOR using UnityEditor; using UnityEngine.SceneManagement; [ExecuteAlways] #endif public class MapManager : MonoBehaviour { private TerrainGridSystem _tgs; [SerializeField] [HideInInspector] private TextAsset _mapDataJson; private MapData _mapData; private Map _map; private CameraController _cameraController; public TerrainGridSystem TGS { get { if (_tgs == null) { var allTgs = FindObjectsOfType(); _tgs = allTgs.FirstOrDefault(t => t.gameObject.scene == gameObject.scene); } return _tgs; } } public TextAsset MapDataJson { get => _mapDataJson; set { if (_mapDataJson != value) { var data = JsonToMapData(value); _mapDataJson = value; if (data != null) { Refresh(); } else { _tgs.TerritoryDestroyAll(); } } } } public MapData MapData { get { if (_mapData == null) { var data = JsonToMapData(MapDataJson); if (data != null) { _mapData = data; TGS.columnCount = _mapData.Width; TGS.rowCount = _mapData.Height; } } return _mapData; } } public Map Map { get { if (_map == null && MapData != null) { _map = MapUtils.LoadMap(TGS, MapData); if (_map != null && CameraController) MapUtils.BindCameraController(CameraController.GetComponent(), _map); } return _map; } } public CameraController CameraController { get { if (_cameraController == null) { var cameras = FindObjectsOfType(); foreach (var cam in cameras) { if (cam.gameObject.scene == gameObject.scene) { var cameraController = cam.GetComponent(); if (cameraController) { _cameraController = cameraController; break; } } } } return _cameraController; } } public void Refresh() { _mapData = null; _map = null; if (_mapDataJson == null) return; TGS.showCells = true; } private MapData JsonToMapData(TextAsset jsonText) { if (jsonText != null) { var jsonStr = jsonText.text; if (string.IsNullOrEmpty(jsonStr)) { var mapData = new MapData(); //mapData.ResetBlocks(); return mapData; } else { //newtowsoft的Json序列化JsonIgnore不起作用,先用Unity的 //return JsonConvert.DeserializeObject(jsonStr); return JsonUtility.FromJson(jsonStr); } } return null; } /*// 保存需要指示的地格索引 25.4.2 改为进游戏动态读取地格属性 public void SaveBuffObjCellIndex(Dictionary cells) { if (cells is { Count: > 0 }) { foreach (var cellData in cells) { var showBuffData = new MapData.ShowBuffData { cellIndex = cellData.Key, path = cellData.Value }; Map.MapData.showBuffPoints.Add(showBuffData); } } }*/ public void SaveMapData() { #if UNITY_EDITOR var currentScene = gameObject.scene; if (currentScene.name.Contains("_PostProcess")) return; if (_mapDataJson != null && _mapData != null && currentScene == SceneManager.GetActiveScene()) { var path = AssetDatabase.GetAssetPath(_mapDataJson); //newtowsoft的Json序列化JsonIgnore不起作用,先用Unity的 //JsonHelper.SaveJson(path, _mapData); var jsonStr = JsonUtility.ToJson(_mapData, true); File.WriteAllText(path, jsonStr); // SaveArtRoot(currentScene); AssetDatabase.Refresh(); } #endif } #if UNITY_EDITOR private void SaveArtRoot(Scene currentScene) { var artRoot = GameObject.Find("Art"); if (artRoot == null) { var postProcess = FindObjectsOfType(); if (postProcess.Length > 0) { artRoot = postProcess[0].combinedObjectsRoot.gameObject; } } if (artRoot == null || IsPrefabOrVariant(artRoot)) return; var savePath = GetUniquePrefabPath(currentScene.name); PrefabUtility.SaveAsPrefabAssetAndConnect(artRoot, savePath, InteractionMode.UserAction); DebugUtil.Log($"保存地图数据成功!保存Art预制体{savePath}"); } private bool IsPrefabOrVariant(GameObject obj) { if (PrefabUtility.IsPartOfPrefabAsset(obj)) return true; if (PrefabUtility.GetPrefabInstanceStatus(obj) != PrefabInstanceStatus.NotAPrefab) return true; return false; } #endif private string GetUniquePrefabPath(string sceneName, int suffix = 0) { var fileName = suffix == 0 ? $"Art_{sceneName}" : $"Art_{sceneName}_{suffix}"; var savePath = $"Assets/Scenes/Maps/LevelArt/{fileName}.prefab"; if (File.Exists(savePath)) { DebugUtil.Log($"预制体 {fileName}.prefab 已存在,将使用新名称"); return GetUniquePrefabPath(sceneName, suffix + 1); } return savePath; } private void OnEnable() { if (!Application.isPlaying) { Refresh(); UpdateBlock(); } } /// /// 地编使用 /// public void UpdateBlock() { if (MapData == null || Map == null || TGS == null) return; TGS.colorizeTerritories = false; TGS.showCells = true; var terrainTypeConfig = TerrainTypeConfig.TerrainTypeProperties; if (terrainTypeConfig.Count <= 0) { DebugUtil.LogError("请重启,无法正确读取地格类型"); return; } MapData.showBuffPoints.Clear(); for (var i = 0; i < MapData.BlocksData.Count; i++) { var blockData = MapData.BlocksData[i]; if (!blockData.IsDefaultTerrainType()) { var prop = terrainTypeConfig[blockData.TerrainTypeIndex]; TGS.CellToggleRegionSurface(i, true, prop.Color); if (!string.IsNullOrEmpty(prop.buffObjectPath)) { MapData.showBuffPoints.Add(new MapData.ShowBuffData { cellIndex = i, path = prop.buffObjectPath, }); } } } } private void OnDestroy() { if (YooAssetBuildStatus.isInBuild) return; if (!Application.isPlaying) SaveMapData(); } }