350 lines
9.6 KiB
C#
350 lines
9.6 KiB
C#
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;
|
||
|
||
/// <summary>
|
||
/// 军团地图
|
||
/// </summary>
|
||
[HideInInspector] public bool isLegionMap;
|
||
|
||
public TerrainGridSystem TGS
|
||
{
|
||
get
|
||
{
|
||
if (_tgs is null)
|
||
{
|
||
var allTgs = FindObjectsOfType<TerrainGridSystem>();
|
||
_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<Camera>(), _map);
|
||
}
|
||
|
||
return _map;
|
||
}
|
||
}
|
||
|
||
public CameraController CameraController
|
||
{
|
||
get
|
||
{
|
||
if (_cameraController is 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 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<MapData>(jsonStr);
|
||
return JsonUtility.FromJson<MapData>(jsonStr);
|
||
}
|
||
}
|
||
|
||
return null;
|
||
}
|
||
|
||
/*// 保存需要指示的地格索引 25.4.2 改为进游戏动态读取地格属性
|
||
public void SaveBuffObjCellIndex(Dictionary<int, string> 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();
|
||
}
|
||
|
||
/// <summary>
|
||
/// 地编使用
|
||
/// </summary>
|
||
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,
|
||
});
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
/// <summary>
|
||
/// 地编使用
|
||
/// </summary>
|
||
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<PostProcessInstructor>();
|
||
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
|
||
} |