You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

474 lines
16 KiB

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(t2up, 3, 0);
CreatePlaceSpecial(h2, 4, 0);
CreatePlaceSpecial(h2, 5, 0);
CreatePlaceSpecial(h2, 6, 0);
CreatePlaceSpecial(h2, 7, 0);
CreatePlaceSpecial(h2, 8, 0);
CreatePlaceSpecial(h2, 9, 0);
CreatePlaceSpecial(t2up, 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(t2down, 3, 7);
CreatePlaceSpecial(h2, 4, 7);
CreatePlaceSpecial(h2, 5, 7);
CreatePlaceSpecial(h2, 6, 7);
CreatePlaceSpecial(h2, 7, 7);
CreatePlaceSpecial(h2, 8, 7);
CreatePlaceSpecial(h2, 9, 7);
CreatePlaceSpecial(t2down, 10, 7);
CreatePlaceSpecial(h2, 11, 7);
CreatePlaceSpecial(h2, 12, 7);
CreatePlaceSpecial(w[2], 13, 7);
CreatePlaceSpecial(v2, 0, 1);
CreatePlaceSpecial(t2right, 0, 2);
CreatePlaceSpecial(v2, 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(v2, 13, 4);
CreatePlaceSpecial(t2left, 13, 5);
CreatePlaceSpecial(v2, 13, 6);
//特殊建筑
gridMap[1][3].isPlace = true;
gridMap[7][5].isPlace = true;
gridMap[5][2].isPlace = true;
gridMap[8][2].isPlace = true;
gridMap[11][4].isPlace = true;
gridMap[1][3].gridType = GridType.Special;
gridMap[7][5].gridType = GridType.Special;
gridMap[5][2].gridType = GridType.Special;
gridMap[8][2].gridType = GridType.Special;
gridMap[11][4].gridType = GridType.Special;
AddGridInfo(3, 0);
AddGridInfo(10, 0);
AddGridInfo(3, 7);
AddGridInfo(10, 7);
AddGridInfo(0, 2);
AddGridInfo(13, 5);
}
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();
StartCoroutine(Wait(()=> {
EduCoderTool.WebConnecter.Singleton.SendResultToWeb(true);
},2f));
}
}
}
IEnumerator Wait(Action action,float t)
{
yield return new WaitForSeconds(t);
action();
}
}
}