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(float width, float height, float sideWidth, float sideHeight)
{
ClearMapGrid();
map = new Map(width, height, sideWidth, sideHeight);
map.SetMapId(1000);
//默认设置半透明0.3
map.ChangeGridAlpha(0.4f);
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 int GetMapY(Vector3 pos)
{
int posIndex = Mathf.FloorToInt(pos.x + Mathf.FloorToInt(pos.z) * map.horizontalNumber);
return map.selector.GetGridData()[posIndex].barrier;
}
///
/// 是否打开了地图
///
///
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 int horizontalNumber { get { return (int)(width / sideWidth); } }
public int verticalNumber { get { return (int)(height / sideHeight); } }
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(horizontalNumber * sideWidth, verticalNumber * sideHeight, sideWidth, sideHeight);
map.SetMapId(mapId);
GridSelector.RenderData[] data = map.selector.GetGridData();
for (int i = 0; i < horizontalNumber * verticalNumber; i++) {
data[i].barrier = br.ReadInt32();
}
map.selector.RefreshPlaneRender();
return map;
}
}