using UnityEngine; using System.IO; using UnityEditor; using System; //[ExecuteAlways] public partial class MapManager : MonoBehaviour { public Material gridMat; //public ComputeShader computeShader; public LineRenderer line; public Map map { get; private set; } public event Action onMapCreated; public CellType cellType; public Map GenerateMap(int mapid, float width, float height, float sideWidth, float sideHeight) { ClearMapGrid(); map = new Map(width, height, sideWidth, sideHeight); map.SetMapId(mapid); //默认设置半透明0.3 map.ChangeGridAlpha(0.25f); onMapCreated?.Invoke(); return map; } public void ClearMapGrid() { if (map != null) { map.Release(); map = null; } } public void HideMapGrid() { if(map != null && map.mapGrid != null) map.mapGrid.gameObject.SetActive(false); } public void ShowMapGrid() { if (map != null && map.mapGrid != null) map.mapGrid.gameObject.SetActive(true); } public void ChangeGridAlpha(float alpha) { if (map == null) { return; } map.ChangeGridAlpha(alpha); } public void ChangeGridHeight(float height) { if (map == null) { return; } int spaceHight = (int)Math.Ceiling(height * 100); //4米为一档 map.ChangeGridHight(spaceHight); } public void ShowOrHideGrid() { if (map == null) return; map.mapGrid.gameObject.SetActive(!map.mapGrid.activeInHierarchy); } /// /// 是否打开了地图 /// /// public bool isOpenMap(bool isTips = true) { if (map == null || map.selector == null) { if (isTips) UIWindow.Instance.ShowMessage("当前没有可编辑地图,请打开地图!"); return false; } return true; } public void SaveMapObs() { if (!MapManager.Instance.isOpenMap()) return; string path = PathUtil.GetObsPath(MapManager.Instance._curOpenMapId, "Obs"); string tmp = path.Substring(0, path.LastIndexOf('/')); if (!Directory.Exists(tmp)) Directory.CreateDirectory(tmp); if (File.Exists(path)) File.Delete(path); using (FileStream fs = new FileStream(path, FileMode.OpenOrCreate, FileAccess.Write)) { BinaryWriter bw = new BinaryWriter(fs); Map.Serialize(MapManager.Instance.map, bw); bw.Close(); } #if UNITY_EDITOR AssetDatabase.Refresh(); #endif } public bool LoadMapObs(int mapId) { string path = PathUtil.GetObsPath(MapManager.Instance._curOpenMapId, "Obs"); if (!File.Exists(path)) return false; if (map != null) { map.Release(); map = null; } using (FileStream fs = new FileStream(path, FileMode.Open, FileAccess.Read)) { BinaryReader br = new BinaryReader(fs); map = Map.Deserialize(br); br.Close(); } return true; } } public partial class Map { public GameObject mapGrid; public GridSelector selector; public int mapId { get; private set; } public float width { get; private set; } public float height { get; private set; } public float sideWidth { get; private set; } public float sideHeight { get; private set; } public Map(float width, float height, float sideWidth,float sideHeight) { this.width = width; this.height = height; this.sideWidth = sideWidth; this.sideHeight = sideHeight; mapGrid = CreateMapGrid(); selector = mapGrid.AddComponent(); selector.OnMapCreated(this); mapGrid.transform.parent = MapManager.Instance.mapGridParent; mapGrid.transform.localPosition = Vector3.zero; mapGrid.transform.localEulerAngles = new Vector3(-90,0,0); //创建地图的时候需要赋值一下当前类型 selector.CellType = MapManager.Instance.cellType; } private GameObject CreateMapGrid() { Mesh mesh = new Mesh(); Vector3[] vertices = new Vector3[4]; vertices[0] = new Vector3(0f, 0f, 0f); vertices[1] = new Vector3(0f, 0f, height); vertices[2] = new Vector3(width, 0f, height); vertices[3] = new Vector3(width, 0f, 0f); mesh.vertices = vertices; Vector2[] uv = new Vector2[4]; uv[0] = new Vector2(0, 0); uv[1] = new Vector2(0, 1); uv[2] = new Vector2(1, 1); uv[3] = new Vector2(1, 0); mesh.uv = uv; int[] triangles = new int[6] { 0, 1, 2, 0, 2, 3 }; mesh.triangles = triangles; Vector3[] normals = new Vector3[4] { Vector3.up, Vector3.up, Vector3.up, Vector3.up }; mesh.normals = normals; GameObject go = new GameObject("Grid"); go.AddComponent().mesh = mesh; go.AddComponent().sharedMaterial = MapManager.Instance.gridMat; go.AddComponent().sharedMesh = mesh; return go; } public void SetMapId(int mapId) { this.mapId = mapId; } public void ChangeGridAlpha(float alpha) { mapGrid.GetComponent().material.SetFloat("_Alpha", alpha); } public void ChangeGridHight(int height) { mapGrid.transform.position = new Vector3(0, height,0); } public void Release() { GameObject.Destroy(mapGrid); mapGrid = null; } public static void Serialize(Map map, BinaryWriter bw) { int width = map.selector.horizontalNumber; int height = map.selector.verticalNumber; bw.Write(map.mapId); bw.Write(width); bw.Write(height); bw.Write((int)Mathf.Round(map.sideWidth * 100)); // 四舍五入确保精度 bw.Write((int)Mathf.Round(map.sideHeight * 100)); // 四舍五入确保精度 GridSelector.RenderData[] data = map.selector.GetGridData(); for (int i = 0, length = data.Length; i < length; i++) { bw.Write(data[i].barrier); } Debug.Log("地图保存成功"); } public static Map Deserialize(BinaryReader br) { int mapId = br.ReadInt32(); int horizontalNumber = br.ReadInt32(); int verticalNumber = br.ReadInt32(); float sideWidth = br.ReadInt32() / 100f; // 读取时直接除以 100 float sideHeight = br.ReadInt32() / 100f; // 读取时直接除以 100 var map = MapManager.Instance.GenerateMap(mapId,horizontalNumber * sideWidth, verticalNumber * sideHeight, sideWidth, sideHeight); GridSelector.RenderData[] data = map.selector.GetGridData(); for (int i = 0; i < horizontalNumber * verticalNumber; i++) { data[i].barrier = br.ReadInt32(); } map.selector.RefreshPlaneRender(); return map; } }