NLDClient-yudde/ProjectNLD/Assets/Code/Scripts/Gameplay/Building/Camp/NewCampBuildDemo.cs

300 lines
7.9 KiB
C#

using System.Collections;
using System.Collections.Generic;
using TGS;
using UnityEngine;
using UnityEngine.InputSystem;
/// <summary>
/// 新营地建造Demo
/// </summary>
public class NewCampBuildDemo : MonoBehaviour
{
/// <summary>
/// 状态
/// </summary>
private enum E_State
{
None,
/// <summary>
/// 拖动状态
/// </summary>
Drag,
/// <summary>
/// 停止状态
/// </summary>
Stop,
}
/// <summary>
/// 网格系统
/// </summary>
[SerializeField]
private TerrainGridSystem gridSystem;
/// <summary>
/// 测试建筑
/// </summary>
[SerializeField]
private Transform tsGo;
/// <summary>
/// 格子状态字典
/// </summary>
private Dictionary<Vector2Int, E_GridState> dicGridState;
/// <summary>
/// 记录所有格子字典
/// </summary>
private Dictionary<Vector2Int, Cell> dicAllGrid;
/// <summary>
/// 格子拖动状态编辑
/// </summary>
private HashSet<Cell> setGridDragEdit;
/// <summary>
/// 测试建筑物
/// </summary>
private Building building;
/// <summary>
/// 射线检测点列表
/// </summary>
private RaycastHit[] hits;
/// <summary>
/// 当前状态
/// </summary>
private E_State state;
private void Awake()
{
setGridDragEdit = new HashSet<Cell>();
dicAllGrid = new Dictionary<Vector2Int, Cell>();
dicGridState = new Dictionary<Vector2Int, E_GridState>();
foreach (Cell cell in gridSystem.cells)
{
Vector2Int vector2Int = new(cell.row, cell.column);
dicAllGrid[vector2Int] = cell;
dicGridState[vector2Int] = E_GridState.Empty;
}
building = new Building(tsGo.gameObject, Vector2Int.zero, Vector2Int.up);
gridSystem.allowHighlightWhileDragging = true;
hits = new RaycastHit[1];
state = E_State.None;
}
private void Update()
{
UpdateInput();
if (state == E_State.Drag)
{
ClearDragCell(); // 还原拖动的格子
Vector2 mousePos = Mouse.current.position.ReadValue();
// 发射射线
Ray ray = Camera.main.ScreenPointToRay(mousePos);
int hitNum = Physics.RaycastNonAlloc(ray.origin, ray.direction, hits);
if (hitNum > 0)
{
RaycastHit firstHit = hits[0];
Cell centerCell = gridSystem.CellGetAtPosition(firstHit.point, true); // 中心点
if (null != centerCell)
{
foreach (Vector2Int offset in building.GridOffsets)
{
Vector2Int newPos = new Vector2Int(centerCell.row, centerCell.column) + offset;
if (dicAllGrid.TryGetValue(newPos, out Cell cell))
{
setGridDragEdit.Add(cell);
gridSystem.CellSetColor(cell, Color.green); // 绿色
Vector3 pos = gridSystem.CellGetPosition(cell);
if (Vector2Int.zero == offset)
tsGo.position = new Vector3(pos.x, tsGo.position.y, pos.z);
}
}
}
}
}
if (state == E_State.Drag && Input.GetMouseButtonDown(0))
{
Build();
}
}
private void UpdateInput()
{
if (Input.GetKeyDown(KeyCode.Alpha1))
{
gridSystem.showCells = false;
gridSystem.showTerritories = false;
gridSystem.showTerritoriesInteriorBorders = false;
gridSystem.HideAll();
}
if (Input.GetKeyDown(KeyCode.Alpha2))
{
gridSystem.showCells = true;
gridSystem.showTerritories = true;
gridSystem.showTerritoriesInteriorBorders = true;
gridSystem.ShowAll();
}
if (Input.GetKeyDown(KeyCode.Alpha3))
{
state = E_State.Drag;
Debug.Log("进入拖动状态");
}
if (Input.GetKeyDown(KeyCode.Alpha4))
{
state = E_State.None;
Debug.Log("进入普通状态");
}
}
/// <summary>
/// 清除拖动的格子
/// </summary>
private void ClearDragCell()
{
foreach (Cell cell in setGridDragEdit)
{
if (dicGridState.TryGetValue(new Vector2Int(cell.row, cell.column), out E_GridState cellState))
SetCellState(cell, cellState);
}
setGridDragEdit.Clear();
}
/// <summary>
/// 校验是否可以放置
/// </summary>
/// <returns></returns>
private bool CheckBuild(Cell centerCell, Vector2Int[] offsets, out List<Cell> listCell)
{
listCell = new List<Cell>();
if (null == centerCell)
return false;
foreach (Vector2Int offset in offsets)
{
Vector2Int newPos = new Vector2Int(centerCell.row, centerCell.column) + offset;
if (!dicGridState.TryGetValue(newPos, out E_GridState gridState))
return false;
if (E_GridState.Using == gridState)
return false;
if(dicAllGrid.TryGetValue(newPos,out Cell cell))
listCell.Add(cell);
}
return true;
}
/// <summary>
/// 建造
/// </summary>
private void Build()
{
// 左键按下
Vector2 mousePos = Mouse.current.position.ReadValue();
// 发射射线
Ray ray = Camera.main.ScreenPointToRay(mousePos);
int hitNum = Physics.RaycastNonAlloc(ray.origin, ray.direction, hits);
if (hitNum <= 0)
return;
RaycastHit firstHit = hits[0];
Cell centerCell = gridSystem.CellGetAtPosition(firstHit.point, true); // 中心点
if (!CheckBuild(centerCell, building.GridOffsets, out List<Cell> listCell))
{
Debug.LogError("该位置不能放置");
return;
}
foreach (Cell cell in listCell)
{
SetCellState(cell, E_GridState.Using);
}
setGridDragEdit.Clear();
state = E_State.None;
}
/// <summary>
/// 设置格子状态
/// </summary>
private void SetCellState(Cell cell, E_GridState gridState)
{
dicGridState[new Vector2Int(cell.row, cell.column)] = gridState;
switch (gridState)
{
case E_GridState.Empty:
{
gridSystem.CellSetColor(cell, new Color(0f, 0f, 0f, 0f)); // 透明
}
break;
case E_GridState.Drag:
{
gridSystem.CellSetColor(cell, Color.green); // 绿色
}
break;
case E_GridState.DragNot:
{
gridSystem.CellSetColor(cell, Color.red); // 红色
}
break;
case E_GridState.Using:
{
gridSystem.CellSetColor(cell, Color.blue); // 蓝色
}
break;
}
}
}
/// <summary>
/// 建筑物
/// </summary>
public class Building
{
/// <summary>
/// 格子偏移
/// </summary>
public Vector2Int[] GridOffsets;
public GameObject Go;
/// <summary>
/// 格子索引
/// </summary>
public int CellIndex = -1;
public Building(GameObject go, params Vector2Int[] gridOffsets)
{
GridOffsets = gridOffsets;
Go = go;
}
}
/// <summary>
/// 格子状态
/// </summary>
public enum E_GridState
{
/// <summary>
/// 空
/// </summary>
Empty,
/// <summary>
/// 拖动可用
/// </summary>
Drag,
/// <summary>
/// 拖动不可用
/// </summary>
DragNot,
/// <summary>
/// 已经使用
/// </summary>
Using,
}