using System; using System.Collections; using System.Collections.Generic; using System.IO; using cfg.FightCfg; using Gameplay; using MapEditor; using PhxhSDK; using PhxhSDK.Phxh; using Sirenix.OdinInspector.Editor; using TGS; using UnityEditor; using UnityEditor.SceneManagement; using UnityEngine; using UnityEngine.Rendering.Universal; using Constants = Framework.Constants; using Object = UnityEngine.Object; [CustomEditor(typeof(MapManager))] public class MapManagerInspector : OdinEditor { private enum ECameraCheckCorner { None, LeftDown, RightDown, LeftUp, RightUp, } private readonly string[] checkCornerType = new[] { "无", "左下角", "右下角", "左上角", "右上角", }; private readonly string[] environmentType = new[] { "平原", "山地", "草原", "林地", "雪地", "泥地", "戈壁", "沙漠", "高原", }; private MapManager Target => target as MapManager; private TerrainGridSystem TGS => Target.TGS; private MapData MapData => Target.MapData; private Map Map => Target.Map; private bool _isEditingGrid; private bool _isEditingCameraOriginPos; private bool _isCheckingCamera; private bool _isEditingCameraInfo; private ECameraCheckCorner _checkType; private const string MapConfigPrefix = "MapData_"; private const string UICanvasCheck = "Assets/Editor/MapEditor/LevelUICheck.prefab"; private GameObject _uiLevelCheck; //scene gui private bool _isHitGround; private Vector3 _mouseHitPosition; private Event _currEvent; private GameObject _ground; private RaycastHit[] _hits = new RaycastHit[1]; protected override void OnEnable() { base.OnEnable(); var allTgs = Object.FindObjectsOfType(); foreach (var tgs in allTgs) { if (tgs != TGS) { foreach (Transform child in tgs.transform) { child.gameObject.SetActive(false); } } } DeActiveScene(); } private void DeActiveScene() { var sceneManagers = FindObjectsOfType(); foreach (var sceneManager in sceneManagers) { SceneVisibilityManager.instance.DisablePicking(sceneManager.Art.gameObject, true); } } protected override void OnDisable() { if (_uiLevelCheck) DestroyImmediate(_uiLevelCheck); if (GameObject.Find("LevelUICheck(Clone)")) DestroyImmediate(GameObject.Find("LevelUICheck(Clone)")); base.OnDisable(); Target.SaveMapData(); } public override void OnInspectorGUI() { if (Application.isPlaying) return; base.OnInspectorGUI(); DrawCreateMapData(); DrawMapData(); EditorSceneManager.MarkSceneDirty(Target.gameObject.scene); } private void DrawCreateMapData() { if (GUILayout.Button("创建地图配置")) { var mapDataDir = Path.GetDirectoryName(Constants.MAP_CONFIG_FORMAT_PATH); var dataPath = EditorUtil.GetAssetUniquePath($"{mapDataDir}/{MapConfigPrefix + Target.gameObject.scene.name}.json", out var textName); using (var fileStream = File.Create(dataPath)) { } AssetDatabase.Refresh(); var textAsset = AssetDatabase.LoadAssetAtPath(dataPath); EditorGUIUtility.PingObject(textAsset); Target.MapDataJson = textAsset; } } private void DrawMapData() { Target.MapDataJson = EditorGUILayout.ObjectField("地图配置", Target.MapDataJson, typeof(TextAsset), false) as TextAsset; if (Target.MapDataJson != null) { EditorGUI.BeginChangeCheck(); var column = EditorGUILayout.DelayedIntField("网格宽度", TGS.columnCount); var raw = EditorGUILayout.DelayedIntField("网格高度", TGS.rowCount); if (EditorGUI.EndChangeCheck()) { var width = column; var height = raw; MapData.Width = width; MapData.Height = height; TGS.columnCount = width; TGS.rowCount = height; Target.SaveMapData(); Target.Refresh(); } EditorGUI.BeginChangeCheck(); var gridOffset = EditorGUILayout.Vector2Field("网格偏移", new Vector2(TGS.transform.position.x, TGS.transform.position.z)); if (EditorGUI.EndChangeCheck()) { var transform = TGS.transform; transform.position = new Vector3(gridOffset.x, 0, gridOffset.y); MapData.position = transform.position; } MapData.environmentType = (ELevelTerrainType)EditorGUILayout.Popup("环境类型", (int)MapData.environmentType, environmentType); DrawCheckCamera(); DrawCameraOriginPosition(); if (GUILayout.Button("打开网格编辑器")) { MapGridWindow.OpenWindow(Target); } DrawCameraInfo(); if (GUILayout.Button("保存")) { Target.SaveMapData(); } } } private void DrawCameraInfo() { _isEditingCameraInfo = EditorGUILayout.Toggle("编辑相机间距", _isEditingCameraInfo); if (_isEditingCameraInfo) { MapData.cameraMarginInfo.leftMarginInFight = EditorGUILayout.FloatField("战斗中相机左间距", MapData.cameraMarginInfo.leftMarginInFight); MapData.cameraMarginInfo.rightMarginInFight = EditorGUILayout.FloatField("战斗中相机右间距", MapData.cameraMarginInfo.rightMarginInFight); MapData.cameraMarginInfo.topMarginInFight = EditorGUILayout.FloatField("战斗中相机上间距", MapData.cameraMarginInfo.topMarginInFight); MapData.cameraMarginInfo.bottomMarginInFight = EditorGUILayout.FloatField("战斗中相机下间距", MapData.cameraMarginInfo.bottomMarginInFight); MapData.cameraMarginInfo.leftMarginInPre = EditorGUILayout.FloatField("准备前相机左间距", MapData.cameraMarginInfo.leftMarginInPre); MapData.cameraMarginInfo.rightMarginInPre = EditorGUILayout.FloatField("准备前相机右间距", MapData.cameraMarginInfo.rightMarginInPre); MapData.cameraMarginInfo.topMarginInInPre = EditorGUILayout.FloatField("准备前相机上间距", MapData.cameraMarginInfo.topMarginInInPre); MapData.cameraMarginInfo.bottomMarginInPre = EditorGUILayout.FloatField("准备前相机下间距", MapData.cameraMarginInfo.bottomMarginInPre); } } private void DrawCheckCamera() { if (!_isCheckingCamera && GUILayout.Button("检查相机可否超出地图")) { _isCheckingCamera = true; Target.CameraController.GetComponent().orthographicSize = Target.CameraController.CameraMaxSize; if (_uiLevelCheck == null) { var ui = AssetDatabase.LoadAssetAtPath(UICanvasCheck); _uiLevelCheck = Instantiate(ui); var uiCamera = _uiLevelCheck.transform.Find("UICamera").GetComponent(); var baseCameraData = Camera.main?.GetComponent(); baseCameraData?.cameraStack.Add(uiCamera); } } if (_isCheckingCamera && GUILayout.Button("退出相机检查")) { if (_uiLevelCheck) DestroyImmediate(_uiLevelCheck); _isCheckingCamera = false; Target.CameraController.GetComponent().orthographicSize = Target.CameraController.CameraMinSize; } if (_isCheckingCamera) { EditorGUI.BeginChangeCheck(); _checkType = (ECameraCheckCorner)EditorGUILayout.Popup("检查角落", (int)_checkType, checkCornerType); if (EditorGUI.EndChangeCheck()) { switch (_checkType) { case ECameraCheckCorner.None: break; case ECameraCheckCorner.LeftDown: var leftDownPoint = new Vector2Int(0, 0); Target.CameraController.InitializeCameraPosition( Map.BlockPosition2WorldPosition(leftDownPoint)); break; case ECameraCheckCorner.RightDown: var rightDownPoint = new Vector2Int(0, TGS.columnCount - 1); Target.CameraController.InitializeCameraPosition( Map.BlockPosition2WorldPosition(rightDownPoint)); break; case ECameraCheckCorner.LeftUp: var leftUpPoint = new Vector2Int(TGS.rowCount - 1, 0); Target.CameraController.InitializeCameraPosition(Map.BlockPosition2WorldPosition(leftUpPoint)); break; case ECameraCheckCorner.RightUp: var rightUpPoint = new Vector2Int(TGS.rowCount - 1, TGS.columnCount - 1); Target.CameraController.InitializeCameraPosition(Map.BlockPosition2WorldPosition(rightUpPoint)); break; default: break; } } } } private void DrawCameraOriginPosition() { if (!_isEditingCameraOriginPos) { if (GUILayout.Button("编辑相机初始位置")) { _isEditingCameraOriginPos = true; } } else { EditorGUILayout.LabelField("请在场景中点击网格来选取相机初始位置,并在Game窗口中查看"); if (GUILayout.Button("退出编辑相机初始位置")) { _isEditingCameraOriginPos = false; } } } private void OnSceneGUI() { if (!_isEditingCameraOriginPos) return; ResetSceneGUIState(Event.current); DrawMouse(); HandleInput(); } protected void ResetSceneGUIState(Event e) { _isHitGround = false; _mouseHitPosition = Vector3.zero; _currEvent = e; _ground = null; } protected void DrawMouse() { var mousePosSS = _currEvent.mousePosition; var ray = HandleUtility.GUIPointToWorldRay(mousePosSS); var count = Physics.RaycastNonAlloc(ray, _hits, 1000, 1 << LayerMask.NameToLayer("Ground")); if (count > 0) { var hit = _hits[0]; _mouseHitPosition = hit.point; Handles.color = Color.yellow; Handles.DrawSolidDisc(_mouseHitPosition, Vector3.up, 1); _isHitGround = true; _ground = hit.collider.gameObject; } } protected void HandleInput() { if (!_isHitGround) return; var controlID = GUIUtility.GetControlID(FocusType.Passive); var eventType = _currEvent.GetTypeForControl(controlID); switch (eventType) { case EventType.MouseDown: if (_currEvent.button == 0) { GUIUtility.hotControl = controlID; if (_isEditingCameraOriginPos) { var cell = TGS.CellGetAtPosition(_mouseHitPosition, true); if (cell == null) { Debug.LogError("点击点附件没有网格!设置相机初始位置失败!"); return; } MapData.initialCameraPosition = MapData.BlockIndex2Position(cell.index); Target.CameraController.InitializeCameraPosition( Map.BlockPosition2WorldPosition(MapData.initialCameraPosition)); } } break; case EventType.MouseUp: if (GUIUtility.hotControl == controlID && _currEvent.button == 0) { GUIUtility.hotControl = 0; _currEvent.Use(); } break; } } }