2024-09-23 13:52:58 +08:00
|
|
|
|
using TGS;
|
2023-12-15 18:32:21 +08:00
|
|
|
|
using Gameplay;
|
2024-02-21 13:06:50 +08:00
|
|
|
|
using PhxhSDK.AOT;
|
2024-09-23 13:52:58 +08:00
|
|
|
|
using System.Linq;
|
|
|
|
|
|
using UnityEngine;
|
|
|
|
|
|
using File = System.IO.File;
|
|
|
|
|
|
using System.Collections.Generic;
|
2025-08-11 15:52:55 +08:00
|
|
|
|
using PhxhSDK;
|
2024-09-23 13:52:58 +08:00
|
|
|
|
|
2023-12-15 18:32:21 +08:00
|
|
|
|
#if UNITY_EDITOR
|
|
|
|
|
|
using UnityEditor;
|
2024-09-23 13:52:58 +08:00
|
|
|
|
using UnityEngine.SceneManagement;
|
2024-12-05 18:42:25 +08:00
|
|
|
|
|
2024-10-16 12:10:08 +08:00
|
|
|
|
[ExecuteAlways]
|
2023-12-15 18:32:21 +08:00
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
|
|
public class MapManager : MonoBehaviour
|
|
|
|
|
|
{
|
|
|
|
|
|
private TerrainGridSystem _tgs;
|
|
|
|
|
|
|
2024-06-04 14:45:36 +08:00
|
|
|
|
[SerializeField] [HideInInspector] private TextAsset _mapDataJson;
|
2023-12-15 18:32:21 +08:00
|
|
|
|
|
|
|
|
|
|
private MapData _mapData;
|
|
|
|
|
|
|
|
|
|
|
|
private Map _map;
|
|
|
|
|
|
|
2023-12-21 15:05:08 +08:00
|
|
|
|
private CameraController _cameraController;
|
2023-12-15 18:32:21 +08:00
|
|
|
|
|
|
|
|
|
|
public TerrainGridSystem TGS
|
|
|
|
|
|
{
|
|
|
|
|
|
get
|
|
|
|
|
|
{
|
|
|
|
|
|
if (_tgs == null)
|
|
|
|
|
|
{
|
|
|
|
|
|
var allTgs = FindObjectsOfType<TerrainGridSystem>();
|
|
|
|
|
|
_tgs = allTgs.FirstOrDefault(t => t.gameObject.scene == gameObject.scene);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
return _tgs;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
public TextAsset MapDataJson
|
|
|
|
|
|
{
|
|
|
|
|
|
get => _mapDataJson;
|
|
|
|
|
|
set
|
|
|
|
|
|
{
|
2023-12-18 19:42:46 +08:00
|
|
|
|
if (_mapDataJson != value)
|
2023-12-15 18:32:21 +08:00
|
|
|
|
{
|
|
|
|
|
|
var data = JsonToMapData(value);
|
2023-12-18 19:42:46 +08:00
|
|
|
|
_mapDataJson = value;
|
2023-12-15 18:32:21 +08:00
|
|
|
|
if (data != null)
|
|
|
|
|
|
{
|
|
|
|
|
|
Refresh();
|
|
|
|
|
|
}
|
2023-12-20 12:47:57 +08:00
|
|
|
|
else
|
|
|
|
|
|
{
|
|
|
|
|
|
_tgs.TerritoryDestroyAll();
|
|
|
|
|
|
}
|
2023-12-15 18:32:21 +08:00
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
public MapData MapData
|
|
|
|
|
|
{
|
|
|
|
|
|
get
|
|
|
|
|
|
{
|
|
|
|
|
|
if (_mapData == null)
|
|
|
|
|
|
{
|
|
|
|
|
|
var data = JsonToMapData(MapDataJson);
|
|
|
|
|
|
if (data != null)
|
|
|
|
|
|
{
|
|
|
|
|
|
_mapData = data;
|
2023-12-20 12:47:57 +08:00
|
|
|
|
TGS.columnCount = _mapData.Width;
|
|
|
|
|
|
TGS.rowCount = _mapData.Height;
|
2023-12-15 18:32:21 +08:00
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
return _mapData;
|
|
|
|
|
|
}
|
2023-12-21 15:05:08 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
public Map Map
|
|
|
|
|
|
{
|
|
|
|
|
|
get
|
|
|
|
|
|
{
|
|
|
|
|
|
if (_map == null && MapData != null)
|
|
|
|
|
|
{
|
|
|
|
|
|
_map = MapUtils.LoadMap(TGS, MapData);
|
|
|
|
|
|
if (_map != null && CameraController)
|
|
|
|
|
|
MapUtils.BindCameraController(CameraController.GetComponent<Camera>(), _map);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
return _map;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
public CameraController CameraController
|
|
|
|
|
|
{
|
|
|
|
|
|
get
|
|
|
|
|
|
{
|
|
|
|
|
|
if (_cameraController == null)
|
|
|
|
|
|
{
|
|
|
|
|
|
var cameras = FindObjectsOfType<Camera>();
|
|
|
|
|
|
foreach (var cam in cameras)
|
|
|
|
|
|
{
|
|
|
|
|
|
if (cam.gameObject.scene == gameObject.scene)
|
|
|
|
|
|
{
|
|
|
|
|
|
var cameraController = cam.GetComponent<CameraController>();
|
|
|
|
|
|
if (cameraController)
|
|
|
|
|
|
{
|
|
|
|
|
|
_cameraController = cameraController;
|
|
|
|
|
|
break;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
return _cameraController;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
public void Refresh()
|
|
|
|
|
|
{
|
|
|
|
|
|
_mapData = null;
|
|
|
|
|
|
_map = null;
|
|
|
|
|
|
if (_mapDataJson == null)
|
|
|
|
|
|
return;
|
|
|
|
|
|
TGS.showCells = true;
|
2023-12-15 18:32:21 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
private MapData JsonToMapData(TextAsset jsonText)
|
|
|
|
|
|
{
|
|
|
|
|
|
if (jsonText != null)
|
|
|
|
|
|
{
|
|
|
|
|
|
var jsonStr = jsonText.text;
|
|
|
|
|
|
if (string.IsNullOrEmpty(jsonStr))
|
|
|
|
|
|
{
|
|
|
|
|
|
var mapData = new MapData();
|
2023-12-18 19:42:46 +08:00
|
|
|
|
//mapData.ResetBlocks();
|
2023-12-15 18:32:21 +08:00
|
|
|
|
return mapData;
|
|
|
|
|
|
}
|
|
|
|
|
|
else
|
|
|
|
|
|
{
|
2023-12-18 19:42:46 +08:00
|
|
|
|
//newtowsoft的Json序列化JsonIgnore不起作用,先用Unity的
|
|
|
|
|
|
//return JsonConvert.DeserializeObject<MapData>(jsonStr);
|
|
|
|
|
|
return JsonUtility.FromJson<MapData>(jsonStr);
|
2023-12-15 18:32:21 +08:00
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
return null;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2025-04-02 15:48:55 +08:00
|
|
|
|
/*// 保存需要指示的地格索引 25.4.2 改为进游戏动态读取地格属性
|
2024-10-09 15:07:23 +08:00
|
|
|
|
public void SaveBuffObjCellIndex(Dictionary<int, string> cells)
|
2024-10-09 14:18:50 +08:00
|
|
|
|
{
|
|
|
|
|
|
if (cells is { Count: > 0 })
|
2024-10-09 15:07:23 +08:00
|
|
|
|
{
|
|
|
|
|
|
foreach (var cellData in cells)
|
|
|
|
|
|
{
|
|
|
|
|
|
var showBuffData = new MapData.ShowBuffData
|
|
|
|
|
|
{
|
|
|
|
|
|
cellIndex = cellData.Key,
|
|
|
|
|
|
path = cellData.Value
|
|
|
|
|
|
};
|
|
|
|
|
|
Map.MapData.showBuffPoints.Add(showBuffData);
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
2025-04-02 15:48:55 +08:00
|
|
|
|
}*/
|
2024-10-09 14:18:50 +08:00
|
|
|
|
|
2023-12-15 18:32:21 +08:00
|
|
|
|
public void SaveMapData()
|
|
|
|
|
|
{
|
|
|
|
|
|
#if UNITY_EDITOR
|
2024-09-23 13:52:58 +08:00
|
|
|
|
var currentScene = gameObject.scene;
|
2025-05-16 19:07:21 +08:00
|
|
|
|
if (currentScene.name.Contains("_PostProcess")) return;
|
2025-06-16 13:16:27 +08:00
|
|
|
|
|
2024-09-23 13:52:58 +08:00
|
|
|
|
if (_mapDataJson != null && _mapData != null && currentScene == SceneManager.GetActiveScene())
|
2023-12-15 18:32:21 +08:00
|
|
|
|
{
|
|
|
|
|
|
var path = AssetDatabase.GetAssetPath(_mapDataJson);
|
2023-12-18 19:42:46 +08:00
|
|
|
|
//newtowsoft的Json序列化JsonIgnore不起作用,先用Unity的
|
|
|
|
|
|
//JsonHelper.SaveJson(path, _mapData);
|
2023-12-20 12:47:57 +08:00
|
|
|
|
var jsonStr = JsonUtility.ToJson(_mapData, true);
|
2023-12-18 19:42:46 +08:00
|
|
|
|
File.WriteAllText(path, jsonStr);
|
2025-06-24 13:29:28 +08:00
|
|
|
|
// SaveArtRoot(currentScene);
|
2025-06-16 13:16:27 +08:00
|
|
|
|
AssetDatabase.Refresh();
|
|
|
|
|
|
}
|
|
|
|
|
|
#endif
|
|
|
|
|
|
}
|
2025-02-20 12:15:10 +08:00
|
|
|
|
|
2025-06-16 14:16:02 +08:00
|
|
|
|
#if UNITY_EDITOR
|
2025-06-16 13:16:27 +08:00
|
|
|
|
private void SaveArtRoot(Scene currentScene)
|
|
|
|
|
|
{
|
|
|
|
|
|
var artRoot = GameObject.Find("Art");
|
|
|
|
|
|
if (artRoot == null)
|
|
|
|
|
|
{
|
|
|
|
|
|
var postProcess = FindObjectsOfType<PostProcessInstructor>();
|
|
|
|
|
|
if (postProcess.Length > 0)
|
2025-02-20 12:15:10 +08:00
|
|
|
|
{
|
2025-06-16 13:16:27 +08:00
|
|
|
|
artRoot = postProcess[0].combinedObjectsRoot.gameObject;
|
2025-02-20 12:15:10 +08:00
|
|
|
|
}
|
2025-06-16 13:16:27 +08:00
|
|
|
|
}
|
2025-02-20 14:09:15 +08:00
|
|
|
|
|
2025-06-16 13:16:27 +08:00
|
|
|
|
if (artRoot == null || IsPrefabOrVariant(artRoot))
|
|
|
|
|
|
return;
|
2025-02-20 12:15:10 +08:00
|
|
|
|
|
2025-06-16 13:16:27 +08:00
|
|
|
|
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;
|
2025-06-16 14:16:02 +08:00
|
|
|
|
|
2025-06-16 13:16:27 +08:00
|
|
|
|
if (PrefabUtility.GetPrefabInstanceStatus(obj) != PrefabInstanceStatus.NotAPrefab)
|
|
|
|
|
|
return true;
|
|
|
|
|
|
|
|
|
|
|
|
return false;
|
|
|
|
|
|
}
|
2025-06-16 14:16:02 +08:00
|
|
|
|
#endif
|
2025-06-16 13:16:27 +08:00
|
|
|
|
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);
|
2023-12-15 18:32:21 +08:00
|
|
|
|
}
|
2025-06-16 13:16:27 +08:00
|
|
|
|
|
|
|
|
|
|
return savePath;
|
2023-12-15 18:32:21 +08:00
|
|
|
|
}
|
2024-06-04 14:45:36 +08:00
|
|
|
|
|
2023-12-20 12:47:57 +08:00
|
|
|
|
private void OnEnable()
|
2023-12-15 18:32:21 +08:00
|
|
|
|
{
|
2025-08-11 15:52:55 +08:00
|
|
|
|
if (BusyWrapper.isBusy)
|
|
|
|
|
|
return;
|
2025-04-28 17:47:20 +08:00
|
|
|
|
if (!Application.isPlaying)
|
2024-12-05 18:42:25 +08:00
|
|
|
|
{
|
2023-12-20 12:47:57 +08:00
|
|
|
|
Refresh();
|
2024-12-05 18:42:25 +08:00
|
|
|
|
UpdateBlock();
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
2025-02-20 14:09:15 +08:00
|
|
|
|
|
2024-12-05 18:42:25 +08:00
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// 地编使用
|
|
|
|
|
|
/// </summary>
|
2024-12-05 18:57:47 +08:00
|
|
|
|
public void UpdateBlock()
|
2024-12-05 18:42:25 +08:00
|
|
|
|
{
|
|
|
|
|
|
if (MapData == null || Map == null || TGS == null) return;
|
|
|
|
|
|
TGS.colorizeTerritories = false;
|
|
|
|
|
|
TGS.showCells = true;
|
2025-06-25 14:29:40 +08:00
|
|
|
|
Dictionary<int, TerrainTypeProperty> terrainTypeConfig = TerrainTypeConfig.DicTerrainTypePropertie;
|
2024-12-05 18:42:25 +08:00
|
|
|
|
if (terrainTypeConfig.Count <= 0)
|
|
|
|
|
|
{
|
|
|
|
|
|
DebugUtil.LogError("请重启,无法正确读取地格类型");
|
|
|
|
|
|
return;
|
|
|
|
|
|
}
|
2025-04-18 14:04:30 +08:00
|
|
|
|
|
2025-04-02 16:04:07 +08:00
|
|
|
|
MapData.showBuffPoints.Clear();
|
2024-12-05 18:42:25 +08:00
|
|
|
|
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);
|
2025-04-02 15:48:55 +08:00
|
|
|
|
if (!string.IsNullOrEmpty(prop.buffObjectPath))
|
|
|
|
|
|
{
|
|
|
|
|
|
MapData.showBuffPoints.Add(new MapData.ShowBuffData
|
|
|
|
|
|
{
|
|
|
|
|
|
cellIndex = i,
|
|
|
|
|
|
path = prop.buffObjectPath,
|
|
|
|
|
|
});
|
|
|
|
|
|
}
|
2024-12-05 18:42:25 +08:00
|
|
|
|
}
|
|
|
|
|
|
}
|
2023-12-15 18:32:21 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
private void OnDestroy()
|
|
|
|
|
|
{
|
2025-08-11 15:52:55 +08:00
|
|
|
|
if (BusyWrapper.isBusy)
|
2024-02-21 13:06:50 +08:00
|
|
|
|
return;
|
2023-12-20 12:47:57 +08:00
|
|
|
|
if (!Application.isPlaying)
|
|
|
|
|
|
SaveMapData();
|
2023-12-15 18:32:21 +08:00
|
|
|
|
}
|
|
|
|
|
|
}
|