319 lines
9.8 KiB
C#
319 lines
9.8 KiB
C#
using System;
|
||
using System.Collections;
|
||
using System.Collections.Generic;
|
||
using System.IO;
|
||
using Framework;
|
||
using Gameplay;
|
||
using MapEditor;
|
||
using PhxhSDK.Phxh;
|
||
using Sirenix.OdinInspector.Editor;
|
||
using TGS;
|
||
using UnityEditor;
|
||
using UnityEditor.SceneManagement;
|
||
using UnityEngine;
|
||
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 ECameraCheckCorner _checkType;
|
||
|
||
//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<TerrainGridSystem>();
|
||
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<NLDSceneManager>();
|
||
foreach (var sceneManager in sceneManagers)
|
||
{
|
||
SceneVisibilityManager.instance.DisablePicking(sceneManager.Art.gameObject, true);
|
||
}
|
||
}
|
||
|
||
protected override void OnDisable()
|
||
{
|
||
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}/{Target.gameObject.scene.name}.json", out var textName);
|
||
using (var fileStream = File.Create(dataPath))
|
||
{
|
||
}
|
||
|
||
AssetDatabase.Refresh();
|
||
var textAsset = AssetDatabase.LoadAssetAtPath<TextAsset>(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 =
|
||
(MapData.EnvironmentType)EditorGUILayout.Popup("环境类型", (int)MapData.environmentType, environmentType);
|
||
|
||
DrawCheckCamera();
|
||
DrawCameraOriginPosition();
|
||
|
||
if (GUILayout.Button("打开网格编辑器"))
|
||
{
|
||
MapGridWindow.OpenWindow(Target);
|
||
}
|
||
|
||
if (GUILayout.Button("保存"))
|
||
{
|
||
Target.SaveMapData();
|
||
}
|
||
}
|
||
}
|
||
|
||
private void DrawCheckCamera()
|
||
{
|
||
if (!_isCheckingCamera && GUILayout.Button("检查相机可否超出地图"))
|
||
{
|
||
_isCheckingCamera = true;
|
||
Target.CameraController.GetComponent<Camera>().orthographicSize = Target.CameraController.CameraMaxSize;
|
||
}
|
||
|
||
if (_isCheckingCamera && GUILayout.Button("退出相机检查"))
|
||
{
|
||
_isCheckingCamera = false;
|
||
Target.CameraController.GetComponent<Camera>().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;
|
||
}
|
||
}
|
||
} |