NLDClient-yudde/ProjectNLD/Assets/Editor/MapEditor/MapEditorUtils.cs

326 lines
11 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

using Framework;
using Gameplay;
using NPOI.SS.Formula.Functions;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using Cysharp.Threading.Tasks;
using TGS;
using UnityEditor;
using UnityEditor.SceneManagement;
using UnityEngine;
using UnityEngine.SceneManagement;
using UnityEngine.UIElements;
using static UnityEditor.Searcher.SearcherWindow.Alignment;
using Cell = TGS.Cell;
public class EditorMap
{
private static EditorMap _instance;
public static EditorMap Instance
{
get
{
if (_instance == null)
{
_instance = new EditorMap();
}
return _instance;
}
}
public delegate void OnMapChanged();
public OnMapChanged onMapChanged;
public Map Current
{
get => _map;
set
{
_map = value;
onMapChanged?.Invoke();
}
}
private Map _map;
}
public class MapEditorUtils
{
public const float UPP = 100;
public static Dictionary<GameObject, List<int>> mapObjectOccupyCells = new Dictionary<GameObject, List<int>>();
// public static Map CreateNewMap(int id, string name, int column, int row, string backgroundPath, MapData.EnvironmentType environmentType)
// {
// OpenMapScene();
//
// var asset = AssetDatabase.LoadAssetAtPath<GameObject>(MapEditorConstant.MapTemplatePrefab);
// var root = GameObject.Instantiate(asset);
// var tgs = root.GetComponentInChildren<TerrainGridSystem>();
//
// tgs.columnCount = column;
// tgs.rowCount = row;
//
// MapData mapData = new MapData(id, name, column, row, environmentType);
// var map = Map.Create(root, mapData);
// map.SetGroundTexture(AssetDatabase.LoadAssetAtPath<Texture2D>(backgroundPath));
// map.ShowInfo((int)Map.InfoMask.ShowAll);
// ResetCamera();
// return map;
// }
public static void OpenMapScene()
{
//GameSceneManager.Instance.ChangeScene(GameSceneManager.EnumScene.GameLevel);
var scene = SceneManager.GetActiveScene();
if (scene.path == MapEditorConstant.MapEditorScene)
{
return;
}
else
{
EditorSceneManager.OpenScene(MapEditorConstant.MapEditorScene);
}
}
// public static void SaveEditorMap()
// {
// var map = EditorMap.Instance.Current;
// if (map != null)
// {
// var prefabFilePath = string.Format(Constants.MAP_ASSET_FORMAT_PATH, map.GetMapFileName());
//
// // PrefabUtility.SaveAsPrefabAssetAndConnect(map.GameObject,
// // prefabFilePath, InteractionMode.UserAction);
//
// var configFilePath = string.Format(Constants.MAP_CONFIG_FORMAT_PATH, map.GetMapFileName());
// // if (File.Exists(configFilePath))
// // {
// // VersionControlSystem.Checkout(configFilePath);
// // }
// Framework.JsonHelper.SaveJson(configFilePath, map.MapData);
//
// if (File.Exists(prefabFilePath) && File.Exists(configFilePath))
// {
// CustomPopUpWindow.PopUp($"Save Successfully:\n {prefabFilePath} \n {configFilePath} \n");
// }
// }
// }
// public static Map LoadMap(TerrainGridSystem terrainGridSystem,MapData mapData)
// {
// //OpenMapScene();
// //ResetCamera();
// //MapUtils.UnLoadMap(EditorMap.Instance.Current);
// var map = MapUtils.LoadMap(terrainGridSystem,mapData);
// if (map != null)
// {
// map.ShowInfo((int)Map.InfoMask.ShowAll);
// return map;
// }
// return null;
// }
public static void UnLoadMap(EditorMap editorMap)
{
MapUtils.UnLoadMap(editorMap.Current);
editorMap.Current = null;
}
// public static void ResetCamera()
// {
// if (Camera.main == null)
// {
// var camera = new GameObject("Main Camera").AddComponent<Camera>();
// camera.tag = "MainCamera";
// }
//
// var mainCamera = Camera.main;
// var cameraController = mainCamera.gameObject.GetComponent<CameraController>();
// if (!cameraController)
// {
// cameraController = mainCamera.gameObject.AddComponent<CameraController>();
// }
//
// cameraController.Map = EditorMap.Instance.Current != null ? EditorMap.Instance.Current : null;
// mainCamera.orthographic = true;
// mainCamera.orthographicSize = cameraController.CameraMaxSize;
// mainCamera.gameObject.transform.forward = Vector3.down;
// mainCamera.gameObject.transform.up = Vector3.forward;
// if (Application.isPlaying)
// {
// if (mainCamera != null)
// {
// GameObject.DontDestroyOnLoad(mainCamera.gameObject);
// }
// }
// }
/// <summary>
/// 物件自动吸附格子
/// </summary>
/// <param name="mapObject"></param>
public static void ObjectAutoAdsorptionCell(GameObject mapObject)
{
var map = EditorMap.Instance.Current;
MeshFilter meshFilter = mapObject.GetComponentInChildren<MeshFilter>();
if (meshFilter != null)
{
var bounds = CalculateBounds(meshFilter.sharedMesh);
// Debug.Log($"包围盒大小:{bounds.size},包围盒中心位置:{bounds.center},最大:{bounds.max},最小:{bounds.min}");
Vector3 centerWorldPos = mapObject.transform.TransformPoint(new Vector3(bounds.center.x, 0f, bounds.center.z));
Cell cell = map.TerrainGridSystem.CellGetAtPosition(centerWorldPos, true);
if (cell != null)
{
var nearestPoint = FindNearestPoint(cell.index, centerWorldPos);
mapObject.transform.position = nearestPoint;
Vector3 centerWorldPos2 = mapObject.transform.TransformPoint(new Vector3(bounds.center.x, 0f, bounds.center.z));
Vector3 moveVector = mapObject.transform.position - centerWorldPos2;
mapObject.transform.position += moveVector;
CalculateFloorArea(mapObject ,bounds);
}
}
}
/// <summary>
/// 刷地图建筑物占地地块默认刷为0号地块
/// </summary>
public static void CalculateFloorArea(GameObject mapObject, Bounds bounds)
{
Dictionary<int, TerrainTypeProperty> terrainTypeConfig = TerrainTypeConfig.DicTerrainTypePropertie;
var map = EditorMap.Instance.Current;
if (mapObjectOccupyCells.TryGetValue(mapObject, out var cells))
{
foreach (var cell in cells)
{
map.TerrainGridSystem.CellSetColor(cell, Color.clear);
}
cells.Clear();
}
else
{
cells = new List<int>();
mapObjectOccupyCells.Add(mapObject, cells);
}
var lowerLeft = mapObject.transform.TransformPoint(new Vector3(bounds.min.x, 0f, bounds.min.y));
var topRight = mapObject.transform.TransformPoint(new Vector3(bounds.max.x, 0f, bounds.max.y));
var lowerRight = mapObject.transform.TransformPoint(new Vector3(bounds.max.x, 0f, bounds.min.y));
var topLeft = mapObject.transform.TransformPoint(new Vector3(bounds.min.x, 0f, bounds.max.y));
var minPos = new Vector3(Mathf.Min(lowerLeft.x, topRight.x, lowerRight.x, topLeft.x), 0f,
Mathf.Min(lowerLeft.z, topRight.z, lowerRight.z, topLeft.z));
var maxPos = new Vector3(Mathf.Max(lowerLeft.x, topRight.x, lowerRight.x, topLeft.x), 0f,
Mathf.Max(lowerLeft.z, topRight.z, lowerRight.z, topLeft.z));
if (map.TerrainGridSystem.CellGetAtPosition(minPos, true) != null &&
map.TerrainGridSystem.CellGetAtPosition(maxPos, true) != null)
{
var minCellPos = map.TGSCellIndex2BlockPosition(map.TerrainGridSystem.CellGetAtPosition(minPos, true).index);
var maxCellPos = map.TGSCellIndex2BlockPosition(map.TerrainGridSystem.CellGetAtPosition(maxPos, true).index);
var minX = Mathf.Min(minCellPos.x, maxCellPos.x);
var maxX = Mathf.Max(minCellPos.x, maxCellPos.x);
var minY = Mathf.Min(minCellPos.y, maxCellPos.y);
var maxY = Mathf.Max(minCellPos.y, maxCellPos.y);
//Debug.Log($"最大y{maxY},最小y{minY},最大x{maxX},最小x{minX}");
for (int i = minX; i <= maxX; ++i)
{
for(int j = minY; j <= maxY; ++j)
{
var cellIndex = map.BlockPosition2TGSCellIndex(new(i, j));
cells.Add(cellIndex);
map.TerrainGridSystem.CellSetColor(cellIndex, terrainTypeConfig[0].Color);
}
}
}
}
/// <summary>
/// 计算3m以下的包围盒大小
/// </summary>
/// <param name="mesh"></param>
/// <returns></returns>
public static Bounds CalculateBounds(Mesh mesh)
{
float limitHeight = 3f;
if (mesh != null)
{
Vector3[] vertices = mesh.vertices;
List<Vector3> limitVertices = vertices.Where(vertex => vertex.z <= limitHeight).ToList();
Bounds bounds = new Bounds(new Vector3(limitVertices[0].x, limitVertices[0].y, 0f), Vector3.zero);
foreach (Vector3 vertex in limitVertices)
{
bounds.Encapsulate(new Vector3(vertex.x, vertex.y, 0f));
}
return bounds;
}
else
{
return new Bounds();
}
}
/// <summary>
/// 寻找六边形中距离最近的点
/// </summary>
/// <param name="cellIndex"></param>
/// <param name="centerPos"></param>
/// <returns></returns>
public static Vector3 FindNearestPoint(int cellIndex, Vector3 centerPos)
{
var map = EditorMap.Instance.Current;
Dictionary<Vector3,float> vertices = new Dictionary<Vector3,float>();
for (int index = 0;index < map.TerrainGridSystem.CellGetVertexCount(cellIndex); index++)
{
var vertex = map.TerrainGridSystem.CellGetVertexPosition(cellIndex, index);
float distance = Vector3.Distance(vertex, centerPos);
vertices.Add(vertex, distance);
}
vertices.Add(map.TGSCellIndex2WorldPosition(cellIndex), Vector3.Distance(map.TGSCellIndex2WorldPosition(cellIndex), centerPos));
var neareatPoint = vertices.FirstOrDefault(x => x.Value == vertices.Values.Min()).Key;
return neareatPoint;
}
}