using System; using System.Diagnostics; using System.IO; using Framework; using Gameplay; using LC.Newtonsoft.Json; using UnityEngine; using Sirenix.OdinInspector; using TGS; using UnityEngine.Serialization; using Debug = DebugUtil; using JsonSerializer = Newtonsoft.Json.JsonSerializer; using Object = UnityEngine.Object; #if UNITY_EDITOR using UnityEditor; using UnityEditor.SceneManagement; #endif [ExecuteAlways] public class MapSceneEditor : MonoBehaviour { private const float UPP = 100; private TerrainGridSystem _tgs; public TerrainGridSystem TGS => _tgs; public bool HasSetGround => _groundMaterial != null && _groundMaterial.mainTexture != null; public bool HasMap => _mapDataJson != null; public MapData MapData { get => _mapData; set { if (_mapData != value) { _mapData = value; if (value == null) { Map = null; } else { Map = MapUtils.LoadMap(_tgs, _mapData); MapUtils.BindCameraController(Camera.main,Map); } } } } public Map Map { get; private set; } public int Width => _tgs.columnCount; public int Height => _tgs.rowCount; [TableColumnWidth(57, Resizable = false)] [PreviewField(Alignment = ObjectFieldAlignment.Center)] [AssetList(Path = (Constants.MAP_TEXTURE_PATH_WITHOUT_ASSET))] [OnValueChanged("OnMapMaterialChanged")] [LabelText("地面图")] [SerializeField] private Material _groundMaterial; [LabelText("地图尺寸")] [LabelWidth(100)] [Indent] [ReadOnly] [SerializeField] private Vector2 _mapScale; [LabelText("摄像机初始视角")] [LabelWidth(150)] [OnValueChanged("OnInitialCameraPositionChanged")] public Vector2Int initialCameraPosition; private void OnInitialCameraPositionChanged() { if (Camera.main != null) { initialCameraPosition.x = Math.Clamp(initialCameraPosition.x, 0, Height - 1); initialCameraPosition.y = Math.Clamp(initialCameraPosition.y, 0, Width - 1); var cameraController = Camera.main.gameObject.GetComponent(); if (_mapData != null) _mapData.initialCameraPosition = initialCameraPosition; cameraController.InitializeCameraPosition(initialCameraPosition); } } public TextAsset MapDataJson { get => _mapDataJson; private set { var data = JsonToMapData(value); if (CheckMapData(data)) { _mapDataJson = value; MapData = data; } else { _mapDataJson = null; MapData = null; } } } [LabelText("地图数据")] [ShowIf("HasSetGround")] [OnValueChanged("OnMapDataJsonChanged")] [SerializeField] private TextAsset _mapDataJson; private void OnMapMaterialChanged() { if (HasSetGround) { _tgs.GetComponent().sharedMaterial = _groundMaterial; _mapScale = (new Vector2(_groundMaterial.mainTexture.width, _groundMaterial.mainTexture.height) / UPP); _tgs.transform.localScale = new Vector3(_mapScale.x, _mapScale.y, 1); _tgs.regularHexagons = false; var width = GetHexCount(_mapScale.x, _tgs.regularHexagonsWidth, false); var height = GetHexCount(_mapScale.y, _tgs.regularHexagonsWidth, true); _tgs.rowCount = height; _tgs.columnCount = width; _tgs.regularHexagons = true; MapDataJson = null; } } [Space] [HideLabel] [ShowIf("HasMap")] [SerializeField] private MapData _mapData; private void OnMapDataJsonChanged(TextAsset k_mapDataJson) { MapDataJson = k_mapDataJson; } [Button("创建地图数据")] [ShowIf("HasSetGround")] [Conditional("UNITY_EDITOR")] private void CreateMapData() { var scene = gameObject.scene; var scenePath = scene.path; var sceneDir = Path.GetDirectoryName(scenePath); var count = AssetDatabase.FindAssets("t:TextAsset", new[] { sceneDir }).Length; var dataName = $"{scene.name}_map_data_{count + 1}"; var dataPath = $"{sceneDir}/{dataName}.json"; using (var fileStream = File.Create(dataPath)) { } AssetDatabase.Refresh(); var textAsset = AssetDatabase.LoadAssetAtPath(dataPath); MapDataJson = textAsset; } private int GetHexCount(float totalLength, float hexWidth, bool isDiagonal) { if (isDiagonal) return Mathf.FloorToInt((4 * totalLength) / (3 * hexWidth) - 1 / 3f); else { var sqrt3 = Mathf.Sqrt(3); var countInFloat = (totalLength - (sqrt3 / 4 * hexWidth)) / (Mathf.Sqrt(3) / 2 * hexWidth); return Mathf.FloorToInt(countInFloat); } } private bool CheckMapData(MapData k_mapData) { if (k_mapData == null) return false; if (k_mapData.width != Width || k_mapData.height != Height) { Debug.LogError("当前地图数据宽高和当前地板宽高不匹配!"); return false; } return true; } private MapData JsonToMapData(TextAsset jsonText) { if (jsonText != null) { var jsonStr = jsonText.text; if (string.IsNullOrEmpty(jsonStr)) { var mapData = new MapData { width = Width, height = Height }; mapData.ResetBlocks(); return mapData; } else { return JsonConvert.DeserializeObject(jsonStr); } } return null; } #region MainLife private void OnEnable() { _tgs = Object.FindObjectOfType(); if (_tgs == null) { Debug.LogError("Terrain Grid System Is Null!"); return; } MapData = JsonToMapData(_mapDataJson); } [Button("保存")] [Conditional("UNITY_EDITOR")] public void SaveMapData() { if (_mapDataJson != null) { var path = AssetDatabase.GetAssetPath(_mapDataJson); JsonHelper.SaveJson(path, _mapData); Debug.Log($"保存地图数据成功!"); EditorSceneManager.SaveOpenScenes(); } } private void OnDestroy() { SaveMapData(); } #endregion }