using TGS;
using Gameplay;
using System.Linq;
using UnityEngine;
using File = System.IO.File;
using PhxhSDK;
#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;
///
/// 军团地图
///
[HideInInspector] public bool isLegionMap;
public TerrainGridSystem TGS
{
get
{
if (_tgs is 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, isLegionMap);
if (_map != null && CameraController)
MapUtils.BindCameraController(CameraController.GetComponent(), _map);
}
return _map;
}
}
public CameraController CameraController
{
get
{
if (_cameraController is 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 is null)
return;
TGS.showCells = true;
#if UNITY_EDITOR
var currentScene = SceneManager.GetActiveScene();
isLegionMap = !string.IsNullOrEmpty(currentScene.name) && currentScene.name.Contains("Legion");
DebugUtil.Log($"当前地图为军团地图:{isLegionMap}");
#endif
}
private MapData JsonToMapData(TextAsset jsonText)
{
if (jsonText is not 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 (Application.isPlaying)
return;
#if UNITY_EDITOR
var currentScene = gameObject.scene;
if (currentScene.name.Contains("_PostProcess"))
{
DebugUtil.LogError("当前在后处理场景,当前数据不会保存,请在原场景处理Map数据");
return;
}
if (_mapDataJson is not 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
}
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 (BusyWrapper.isBusy)
return;
if (!Application.isPlaying)
{
Refresh();
if (isLegionMap)
UpdateLegionBlockInEditor();
else
UpdateBlockInEditor();
}
}
private void OnDestroy()
{
if (BusyWrapper.isBusy)
return;
if (!Application.isPlaying)
SaveMapData();
}
///
/// 地编使用
///
private void UpdateBlockInEditor()
{
if (MapData == null || Map == null || TGS == null) return;
TGS.colorizeTerritories = false;
TGS.showCells = true;
var terrainTypeConfig = TerrainTypeConfig.DicTerrainTypePropertie;
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 UpdateLegionBlockInEditor()
{
if (MapData == null || Map == null || TGS == null) return;
TGS.colorizeTerritories = false;
TGS.showCells = true;
var terrainTypeConfig = LegionTerrainTypeConfig.DicTerrainTypePropertie;
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.IsDefaultLegionTerrainType())
{
var prop = terrainTypeConfig[blockData.LegionTypeIndex];
TGS.CellToggleRegionSurface(i, true, prop.Color);
if (!string.IsNullOrEmpty(prop.buffObjectPath))
{
MapData.showBuffPoints.Add(new MapData.ShowBuffData
{
cellIndex = i,
path = prop.buffObjectPath,
});
}
}
}
}
#region 保存预制体功能
#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
#endregion
}