using Framework; using Gameplay; using Sirenix.OdinInspector; using Sirenix.OdinInspector.Editor; using Sirenix.Utilities; using Sirenix.Utilities.Editor; using System; using System.Collections; using System.Collections.Generic; using System.Linq; using Newtonsoft.Json; using TGS; using UnityEditor; using UnityEngine; using UnityEngine.InputSystem; using UnityEngine.InputSystem.EnhancedTouch; using Object = UnityEngine.Object; using ObjectFieldAlignment = Sirenix.OdinInspector.ObjectFieldAlignment; namespace MapEditor { public class MapGridWindow : OdinEditorWindow { #region Inner Class [Serializable] public class RegionArea { [HorizontalGroup("1")] [ReadOnly] public int id; [HorizontalGroup("1")] [ReadOnly] [LabelText("数量")] public int regionCount; public List positions => _region.positions; private MapData.Region _region; public RegionArea(MapData.Region region) { _region = region; } [Button("编辑"), HorizontalGroup("1")] private void EditorRegion() { var map = thisWindow._map; thisWindow._currEditRegionArea = this; var regionslist = map.MapData.regions; for (int i = 0; i < regionslist.Count; i++) { map.SetRegionColor(i, false, regionColor); } map.SetRegionColor(_region, true, regionColor); canEditorRegion = true; } public void AddPosition(int cellIndex) { if (positions.Contains(cellIndex)) return; positions.Add(cellIndex); regionCount++; thisWindow._map.TerrainGridSystem.CellToggleRegionSurface(cellIndex, true, regionColor); } public void RemovePosition(int cellIndex) { if (!positions.Contains(cellIndex)) return; positions.Remove(cellIndex); regionCount--; thisWindow._map.TerrainGridSystem.CellHideRegionSurface(cellIndex); } } #endregion #region Fields And Properties private static MapGridWindow thisWindow; //1.#FFBF0072 2.#FF960072 private static readonly Color regionColor = MapUtils.GetRGBAColor("FF960072"); private static readonly Color cellBorderColor = new Color(229f, 229f, 229f, 237f); private static readonly float cellBorderWidth = 1f; private static List _terrainTypeConfig; private static bool canEditorRegion = false; private bool EditorNewRegion = false; private string _mapDataJsonStr = ""; private GameObject selectedGameObject; private Vector3 previousPosition; private Vector3 previousRotation; private MapData _currentMapData = null; private RegionArea _currEditRegionArea; private MapManager _currMapManager; private Map _map; #endregion #region Editor [Button("保存")] private void RebuildPrefab() { _currMapManager.SaveMapData(); } [Button("清除网格数据")] private void ClearGridData() { if (EditorUtility.DisplayDialog("清理网格数据", "您是否确认清理地图网格数据", "确认", "取消")) { _currentMapData.ClearGridData(); _map.TerrainGridSystem.TerritoryDestroyAll(); ClearRegionColor(); UpdateRegion(); _currMapManager.SaveMapData(); } } [BoxGroup("地块信息")] [LabelText("刷地块"), Indent] [OnValueChanged("OnCanCanBrushTerrainTypeChanged")] [LabelWidth(100)] [SerializeField] [ShowIf("@!CanEditorAreaType")] private bool CanBrushTerrainType; private void OnCanCanBrushTerrainTypeChanged() { if (CanBrushTerrainType && _map != null) { CanEditorAreaType = false; _map.TerrainGridSystem.colorizeTerritories = true; } } [HorizontalGroup("地块信息/Territory")] [ValueDropdown("GetTerrainTypeProperties")] [Indent] [LabelText("选择地块")] [ShowIf("CanBrushTerrainType")] public int TerrainTypeIndex = 0; [ShowIf("CanBrushTerrainType")] [HorizontalGroup("地块信息/Territory")] [Button(SdfIconType.GearFill, "编辑地块")] public void EditTerrainTypeConfig() { var window = GetWindow(); window.Show(); } [BoxGroup("地区信息")] [HorizontalGroup("地区信息/Region")] [LabelText("编辑地区"), Indent] [OnValueChanged("OnCanEditorAreaTypeChanged")] [LabelWidth(100)] [SerializeField] private bool CanEditorAreaType; private void OnCanEditorAreaTypeChanged() { var map = _map; if (CanEditorAreaType) { CanBrushTerrainType = false; } else { ClearRegionColor(); SceneView.RepaintAll(); canEditorRegion = false; } } [LabelText("地区列表")] [VerticalGroup("地区信息/RegionInfo")] [ShowIf("CanEditorAreaType")] [VerticalGroup("地区信息/RegionInfo"), Indent] [ListDrawerSettings(CustomAddFunction = "CustomAddRegion", CustomRemoveIndexFunction = "CustomRemoveRegion", DraggableItems = false)] public List RegionList = new(); private void CustomAddRegion() { var region = new MapData.Region(); _currentMapData.regions.Add(region); UpdateRegion(); } private void CustomRemoveRegion(int index) { ClearRegionColor(); _currentMapData.regions.RemoveAt(index); UpdateRegion(); } // [Button("切换至游戏视角")] // private void SwitchToGameView() // { // if (Camera.main != null) // { // var cameraController = Camera.main.gameObject.GetComponent(); // cameraController.SwitchCameraView(true); // } // } // // //[HorizontalGroup("地图编辑器/Split/Right/ViewPoint")] // [Button("切换至俯视视角"), Indent] // private void SwitchToDefaultView() // { // if (Camera.main != null) // { // var cameraController = Camera.main.gameObject.GetComponent(); // cameraController.SwitchCameraView(false); // } // } #endregion #region MainLife public static void OpenWindow(MapManager mapSceneEditor) { MapEditorSettings.Init(); thisWindow = GetWindow(); thisWindow.name = "MapGridWindow"; thisWindow.position = GUIHelper.GetEditorWindowRect().AlignCenter(800, 600); thisWindow._currMapManager = mapSceneEditor; thisWindow._currentMapData = null; thisWindow.ShowTab(); thisWindow.LoadMap(mapSceneEditor.TGS, mapSceneEditor.MapData, mapSceneEditor.Map); UnityEditor.Compilation.CompilationPipeline.compilationStarted += OnCompilationStart; } private static void OnCompilationStart(object obj) { thisWindow?.Close(); thisWindow = null; } private void LoadMap(TerrainGridSystem tgs, MapData data, Map map) { _currentMapData = data; _map = map; //MapEditorUtils.LoadMap(tgs, data); _terrainTypeConfig = TerrainTypeConfig.TerrainTypeProperties; _map.TerrainGridSystem.highlightEffect = HighlightEffect.Default; // for (int i = 0; i < _map.MapData.BlocksData.Count; i++) // { // if (_map.MapData.BlocksData[i].TerrainTypeIndex != -1) // { // if (_terrainTypeConfig[_map.MapData.BlocksData[i].TerrainTypeIndex].emptyBlock) // { // _map.TerrainGridSystem.CellSetBorderVisible(i, false); // } // } // } //MapEditorUtils.ResetCamera(); // if (Camera.main != null) // { // var cameraController = Camera.main.gameObject.GetComponent(); // //cameraController.SwitchCameraView(false); // } tgs.OnMouseClickOnGrid += OnMouseClickCell; //tgs.OnMouseMoveOnGrid += OnMouseMoveOnCell; UpdateRegion(); } protected override void OnEnable() { EnhancedTouchSupport.Enable(); TerrainTypeConfig.Load(); base.OnEnable(); } protected override void OnDisable() { EnhancedTouchSupport.Disable(); base.OnDisable(); } protected override void OnGUI() { base.OnGUI(); if (_currMapManager == null || _currMapManager.MapData != _currentMapData) { Debug.Log("地图数据变更,请重新点击编辑网格!"); Close(); } } protected override void OnDestroy() { base.OnDestroy(); if(_currMapManager != null) _currMapManager.SaveMapData(); ClearRegionColor(); //SetCellBorderType(); _map.TerrainGridSystem.OnMouseClickOnGrid -= OnMouseClickCell; //_map.TerrainGridSystem.OnMouseMoveOnGrid -= OnMouseMoveOnCell; //_map.TerrainGridSystem.TerritoryDestroyAll(); UnityEditor.Compilation.CompilationPipeline.compilationStarted -= OnCompilationStart; } #endregion #region Other private void UpdateRegion() { RegionList.Clear(); if (_currentMapData != null) { int index = 0; foreach (var region in _currentMapData.regions) { RegionArea ra = new RegionArea(region); ra.id = index; ra.regionCount = ra.positions.Count; RegionList.Add(ra); index++; } } } private void OnMouseClickCell(TerrainGridSystem tgs, int cellIndex, int buttonIndex) { int leftButton = 0; OnCellOperation(tgs,cellIndex,buttonIndex == leftButton); } private void OnMouseMoveOnCell(TerrainGridSystem tgs,int cellIndex,bool isControl,bool isShift) { OnCellOperation(tgs,cellIndex,isControl); } private void OnCellOperation(TerrainGridSystem tgs, int cellIndex, bool isOpTrue) { if (!CanBrushTerrainType && !CanEditorAreaType) { return; } if (CanEditorAreaType && _currEditRegionArea == null) return; var map = _map; int leftButton = 0; int rightButton = 1; if (isOpTrue && TerrainTypeIndex >= 0 && CanBrushTerrainType) { SetCellTerritory(tgs, cellIndex, TerrainTypeIndex); } else if (!isOpTrue && CanBrushTerrainType) { if (_currentMapData.BlocksData[cellIndex].TerrainTypeIndex == TerrainTypeIndex) { ClearCellTerritory(tgs, cellIndex); } } if (isOpTrue && canEditorRegion) { _currEditRegionArea.AddPosition(cellIndex); } else if (!isOpTrue && canEditorRegion) { _currEditRegionArea.RemovePosition(cellIndex); } } private void SetCellTerritory(TerrainGridSystem tgs, int cellIndex, int TerrainTypeIndex) { var map = _map; // Key: TerrainTypeIndex Value: tgs.territories.index if (!map.TerrainTypeIndexDic.ContainsKey(TerrainTypeIndex)) { Territory territory = tgs.TerritoryCreate(cellIndex); map.TerrainTypeIndexDic.Add(TerrainTypeIndex, map.TerrainTypeIndexDic.Count); territory.fillColor = _terrainTypeConfig[TerrainTypeIndex].Color; } if (_terrainTypeConfig[TerrainTypeIndex].emptyBlock) { map.TerrainGridSystem.CellSetBorderVisible(cellIndex, false); } map?.SetTerrainType(cellIndex, TerrainTypeIndex); tgs.CellSetTerritory(cellIndex, map.TerrainTypeIndexDic[TerrainTypeIndex]); Debug.Log( $"Set Territory, cellIndex ({cellIndex}), terrain type ({TerrainTypeIndex}), name ({_terrainTypeConfig[TerrainTypeIndex].Color})"); } private void ClearCellTerritory(TerrainGridSystem tgs, int cellIndex) { var map = _map; map.TerrainGridSystem.CellSetBorderVisible(cellIndex, true); var tIndex = tgs.CellGetTerritoryIndex(cellIndex); if (tIndex != -1) { tgs.CellSetTerritory(cellIndex, -1); map?.SetTerrainType(cellIndex, -1); Debug.Log($"Cell Clear Territory, cellIndex({cellIndex})"); } } private bool banSaveMapList = false; private void SetCellBorderType() { var map = _map; if (map != null) { map.TerrainGridSystem.cellBorderColor = cellBorderColor / 255f; map.TerrainGridSystem.cellBorderThickness = cellBorderWidth; } } private static IEnumerable GetTerrainTypeProperties() { _terrainTypeConfig = TerrainTypeConfig.TerrainTypeProperties; var list = new ValueDropdownList(); if (_terrainTypeConfig != null) { for (int i = 0; i < _terrainTypeConfig.Count; i++) { list.Add(_terrainTypeConfig[i].name, i); } } return list; } private void ClearRegionColor() { if (_map == null) return; for (int i = 0; i < _map.MapData.regions.Count; i++) { _map.SetRegionColor(i, false, regionColor); } } #endregion } }