using System.Collections; using System.Collections.Generic; using UnityEngine; using System; namespace BuildSystem { [DefaultExecutionOrder(-10)] public class BuildSystemManager : MonoSingleton<BuildSystemManager> { [NonSerialized] public MouseClick mouseClick; public BuildTip buildTip; public SetPanel setPanel; [Header("地图大小")] public Vector2Int mapSize; [Header("grid大小")] public int gridSize; [Header("起始位置")] public Vector3 startPos; [Header("是否可以放置")] public bool isCanPlace; [Header("拆除")] public bool isRemove = false; public Grid[][] gridMap; [Header("转换后的数据")] public List<GridInfo> grid = new List<GridInfo>(); private PlaceObject_SO placeObject_SO;//当前选中的道路 [Header("鼠标是否检测到ui")] public bool isUI = false; [NonSerialized] public PlaceObject placeObj; [Header("放置标识")] public GameObject flag; [Header("部署阶段状态")] public bool oneStageEnd = false; [Header("红绿灯放置阶段状态")] public bool redGreenLightEnd = false; [Header("用于初始化地图")] public PlaceObject_SO t2up; public PlaceObject_SO t2down; public PlaceObject_SO h2; public PlaceObject_SO t2left; public PlaceObject_SO t2right; public PlaceObject_SO v2; public PlaceObject_SO[] w; protected override void Awake() { base.Awake(); mouseClick = GetComponent<MouseClick>(); CreateTerrain(); DontDestroyOnLoad(gameObject); //地图初始化 MapInit(); } /// <summary> /// 创建地形 /// </summary> void CreateTerrain() { //创建地图 gridMap = new Grid[mapSize.x][]; for (int i = 0; i < mapSize.x; i++) { gridMap[i] = new Grid[mapSize.y]; for (int j = 0; j < mapSize.y; j++) { Grid grid = new Grid(i, 0, j); gridMap[i][j] = grid; if (i > 0) { grid.BindLeftAndThis(gridMap[i - 1][j]); } if (j > 0) { grid.BindDownAndThis(gridMap[i][j - 1]); } } } } /// <summary> /// 地图初始化 /// </summary> void MapInit() { CreatePlaceSpecial(w[0], 0, 0); CreatePlaceSpecial(h2, 1, 0); CreatePlaceSpecial(h2, 2, 0); CreatePlaceSpecial(h2, 3, 0); CreatePlaceSpecial(t2up, 4, 0); CreatePlaceSpecial(h2, 5, 0); CreatePlaceSpecial(h2, 6, 0); CreatePlaceSpecial(h2, 7, 0); CreatePlaceSpecial(h2, 8, 0); CreatePlaceSpecial(t2up, 9, 0); CreatePlaceSpecial(h2, 10, 0); CreatePlaceSpecial(h2, 11, 0); CreatePlaceSpecial(h2, 12, 0); CreatePlaceSpecial(w[3], 13, 0); CreatePlaceSpecial(w[1], 0, 7); CreatePlaceSpecial(h2, 1, 7); CreatePlaceSpecial(h2, 2, 7); CreatePlaceSpecial(h2, 3, 7); CreatePlaceSpecial(t2down, 4, 7); CreatePlaceSpecial(h2, 5, 7); CreatePlaceSpecial(h2, 6, 7); CreatePlaceSpecial(h2, 7, 7); CreatePlaceSpecial(h2, 8, 7); CreatePlaceSpecial(t2down, 9, 7); CreatePlaceSpecial(h2, 10, 7); CreatePlaceSpecial(h2, 11, 7); CreatePlaceSpecial(h2, 12, 7); CreatePlaceSpecial(w[2], 13, 7); CreatePlaceSpecial(v2, 0, 1); CreatePlaceSpecial(v2, 0, 2); CreatePlaceSpecial(t2right, 0, 3); CreatePlaceSpecial(v2, 0, 4); CreatePlaceSpecial(v2, 0, 5); CreatePlaceSpecial(v2, 0, 6); CreatePlaceSpecial(v2, 13, 1); CreatePlaceSpecial(v2, 13, 2); CreatePlaceSpecial(v2, 13, 3); CreatePlaceSpecial(t2left, 13, 4); CreatePlaceSpecial(v2, 13, 5); CreatePlaceSpecial(v2, 13, 6); //特殊建筑 gridMap[2][4].isPlace = true; gridMap[7][6].isPlace = true; gridMap[5][3].isPlace = true; gridMap[8][2].isPlace = true; gridMap[11][3].isPlace = true; gridMap[2][4].gridType = GridType.Special; gridMap[7][6].gridType = GridType.Special; gridMap[5][3].gridType = GridType.Special; gridMap[8][2].gridType = GridType.Special; gridMap[11][3].gridType = GridType.Special; AddGridInfo(4, 0); AddGridInfo(9, 0); AddGridInfo(4, 7); AddGridInfo(9, 7); AddGridInfo(0, 3); AddGridInfo(13, 4); } void AddGridInfo(int x, int y) { var gridinfo = gridMap[x][y].placeObject.gameObject.AddComponent<GridInfo>(); grid.Add(gridinfo); gridinfo.TransData(gridMap[x][y]); } /// <summary> /// 创建一个当前选择的物体,用于指示器的更换 /// </summary> /// <returns></returns> PlaceObject CreatePlaceObject() { Transform trans = Instantiate(placeObject_SO.prefab, transform); PlaceObject obj = trans.gameObject.AddComponent<PlaceObject>(); obj.Init(placeObject_SO.nameString, placeObject_SO.width, placeObject_SO.height, placeObject_SO.roadNumberType,placeObject_SO.isHaveRoad,placeObject_SO.roadType, placeObject_SO.roadGoInfo); obj.SetPosition(GetGridPos(mouseClick.MouseInGrid())); return obj; } /// <summary> /// 创建一个物体 /// </summary> /// <param name="place"></param> /// <param name="x"></param> /// <param name="y"></param> void CreatePlace(PlaceObject_SO place, int x, int y) { Transform trans = Instantiate(place.prefab, transform); PlaceObject obj = trans.gameObject.AddComponent<PlaceObject>(); obj.Init(place.nameString, place.width, place.height, place.roadNumberType, place.isHaveRoad, place.roadType,place.roadGoInfo); obj.SetPosition(GetGridPos(new Vector3Int(x, 0, y))); gridMap[x][y].isPlace = true; gridMap[x][y].type = place.roadNumberType; gridMap[x][y].isHaves = place.isHaveRoad; gridMap[x][y].roadType = place.roadType; gridMap[x][y].placeObject = obj; //转换红绿灯需要的信息 if (gridMap[x][y].roadType != RoadType.T && gridMap[x][y].roadType != RoadType.Ten) return; var gridinfo = trans.gameObject.AddComponent<GridInfo>(); grid.Add(gridinfo); gridinfo.TransData(gridMap[x][y]); } /// <summary> /// 移除格子的时候移除信号灯数据 /// </summary> /// <param name="info"></param> public void RemoveGrid(GridInfo info) { if (grid.Contains(info)) { grid.Remove(info); } } /// <summary> /// 创建一个gridtype为初始化类型的数组 /// </summary> /// <param name="place"></param> /// <param name="x"></param> /// <param name="y"></param> void CreatePlaceSpecial(PlaceObject_SO place, int x, int y) { Transform trans = Instantiate(place.prefab, transform); PlaceObject obj = trans.gameObject.AddComponent<PlaceObject>(); obj.Init(place.nameString, place.width, place.height, place.roadNumberType, place.isHaveRoad, place.roadType,Instantiate(place).roadGoInfo); obj.SetPosition(GetGridPos(new Vector3Int(x, 0, y))); gridMap[x][y].isPlace = true; gridMap[x][y].gridType = GridType.Initial; gridMap[x][y].type = place.roadNumberType; gridMap[x][y].isHaves = place.isHaveRoad; gridMap[x][y].roadType = place.roadType; gridMap[x][y].placeObject = obj; } /// <summary> /// 移除某个物体 /// </summary> /// <param name="x"></param> /// <param name="y"></param> void RemovePlace(int x, int y) { RemoveGrid(gridMap[x][y].placeObject.gameObject.GetComponent<GridInfo>()); Destroy(gridMap[x][y].placeObject.gameObject); gridMap[x][y].RemoveInit(); } /// <summary> /// 改变当前的选择的指示器 /// </summary> public void ChangeChoose(PlaceObject_SO placeObject_SO) { this.placeObject_SO = placeObject_SO; if (placeObj) { Destroy(placeObj.gameObject); } placeObj = CreatePlaceObject(); } /// <summary> /// 是否可以创建 /// </summary> public bool isCanCreate() { //将自身大小记录 bool isCreateSuccess = true; Vector3Int start = mouseClick.MouseInGrid(); if (start == new Vector3Int(-1, -1, -1) || gridMap[start.x][start.z].isPlace) { isCreateSuccess = false; } if (!isCreateSuccess) { if (!isUI) { buildTip.ShowTip("当前位置不可创建"); } return false; } //判断类型是否可以放置 if (isCreateSuccess) { if (!gridMap[start.x][start.z].IsCanPlace(placeObj)) { buildTip.ShowTip("当前位置存在放置存在风险"); return false; } } return true; } /// <summary> /// 判断是否可以创建,用于提示 /// </summary> /// <returns></returns> public bool isCanCreateToTip() { //将自身大小记录 bool isCreateSuccess = true; Vector3Int start = mouseClick.MouseInGrid(); if (start == new Vector3Int(-1, -1, -1) || gridMap[start.x][start.z].isPlace) { isCreateSuccess = false; } if (!isCreateSuccess) { return false; } //判断类型是否可以放置 if (isCreateSuccess) { if (!gridMap[start.x][start.z].IsCanPlace(placeObj)) { return false; } } return true; } /// <summary> /// 获取grid的世界坐标 /// </summary> /// <param name="pos"></param> /// <returns></returns> public Vector3 GetGridPos(Vector3Int pos) { if (pos == new Vector3Int(-1, -1, -1)) { return Vector3Int.zero; } return gridMap[pos.x][pos.z].pos; } /// <summary> /// 判断是否通关 /// </summary> /// <returns></returns> public bool IsGameEnd() { //判断是否闭环 for (int i = 0; i < mapSize.x; i++) { for (int j = 0; j < mapSize.y; j++) { if (!gridMap[i][j].isClosedLoop()) { return false; } } } //判断是否有两个十字 int number = 0; for (int i = 0; i < mapSize.x; i++) { for (int j = 0; j < mapSize.y; j++) { if (gridMap[i][j].isPlace && gridMap[i][j].roadType == RoadType.Ten) { number++; } } } if (number < 2) { return false; } return true; } private void Update() { //更新格子的相邻道路 for (int i = 0; i < mapSize.x; i++) { for (int j = 0; j < mapSize.y; j++) { gridMap[i][j].InitGround(); } } if (!oneStageEnd) { //物体跟随鼠标 if (placeObj && isCanPlace) { if (mouseClick.MouseInGrid() != new Vector3Int(-1, -1, -1)) { placeObj.SetPosition(GetGridPos(mouseClick.MouseInGrid())); } } ////创建物体 if (Input.GetMouseButtonDown(0) && placeObj && isCanPlace && isCanCreate()) { CreatePlace(placeObject_SO, mouseClick.MouseInGrid().x, mouseClick.MouseInGrid().z); } else if (Input.GetMouseButtonDown(1) && mouseClick.MouseInGrid() != new Vector3Int(-1, -1, -1)) { if (gridMap[mouseClick.MouseInGrid().x][mouseClick.MouseInGrid().z].placeObject) { if (gridMap[mouseClick.MouseInGrid().x][mouseClick.MouseInGrid().z].gridType == GridType.General) { RemovePlace(mouseClick.MouseInGrid().x, mouseClick.MouseInGrid().z); buildTip.ShowTip("拆除提示"); } } } //变色提示 if (placeObj) { flag.transform.position = placeObj.transform.position - new Vector3(0, 0.5f, 0); if (isCanCreateToTip()) { flag.GetComponent<MeshRenderer>().material.SetColor("_Color", new Color32(48, 255, 30, 128)); } else { flag.GetComponent<MeshRenderer>().material.SetColor("_Color", new Color32(255, 41, 0, 128)); } } //判断通关 if (IsGameEnd() && !oneStageEnd) { oneStageEnd = true; flag.SetActive(false); UIManager.Instance.OneStageEnd(); Debug.Log("部署阶段结束"); //更新格子的相邻道路 for (int i = 0; i < mapSize.x; i++) { for (int j = 0; j < mapSize.y; j++) { gridMap[i][j].InitGround(); } } Debug.Log(grid.Count); } } if (!redGreenLightEnd && oneStageEnd) { bool flag = true; foreach (GridInfo info in grid) { if (!info.isPlaceLight) { flag = false; break; } } //红绿灯放置阶段结束 if (flag) { redGreenLightEnd = true; Debug.Log("红绿灯放置阶段结束"); UIManager.Instance.TwoStageEnd(); } } } IEnumerator Wait(Action action,float t) { yield return new WaitForSeconds(t); action(); } } }