278 lines
8.2 KiB
C#
278 lines
8.2 KiB
C#
using cfg.CampCfg;
|
|
using Gameplay.Building.Impl;
|
|
using PhxhSDK;
|
|
using System.Collections.Generic;
|
|
using TGS;
|
|
using UnityEngine;
|
|
using UnityEngine.InputSystem;
|
|
using UnityEngine.Rendering;
|
|
|
|
namespace Gameplay.Camp
|
|
{
|
|
public sealed partial class Camp
|
|
{
|
|
/// <summary>
|
|
/// 射线检测点列表
|
|
/// </summary>
|
|
private RaycastHit[] hits;
|
|
/// <summary>
|
|
/// 编辑模式下地板状态
|
|
/// </summary>
|
|
private Dictionary<int, E_CampCellState> dicEditCellState;
|
|
/// <summary>
|
|
/// 编辑模式下未保存的营地单位集合
|
|
/// </summary>
|
|
private HashSet<CampUnitBase> setEditUnit;
|
|
/// <summary>
|
|
/// 修改过的地板颜色集合
|
|
/// </summary>
|
|
private HashSet<Cell> setCellDrag;
|
|
/// <summary>
|
|
/// 当前拖动的建筑单位
|
|
/// </summary>
|
|
private BuildingCampUnit buildingCampUnit;
|
|
|
|
/// <summary>
|
|
/// 编辑状态
|
|
/// </summary>
|
|
public bool IsEdit { get; private set; }
|
|
|
|
/// <summary>
|
|
/// 是否拖动状态
|
|
/// </summary>
|
|
public bool IsDrag { get; private set; }
|
|
|
|
private void InitEdit()
|
|
{
|
|
hits = new RaycastHit[1];
|
|
dicEditCellState = new Dictionary<int, E_CampCellState>();
|
|
setEditUnit = new HashSet<CampUnitBase>();
|
|
setCellDrag = new HashSet<Cell>();
|
|
|
|
IsEdit = false;
|
|
}
|
|
|
|
/// <summary>
|
|
/// 进入编辑模式
|
|
/// </summary>
|
|
public void SetInfoByEdit()
|
|
{
|
|
setCellDrag.Clear();
|
|
|
|
foreach (var kv in dicCellStateByIndex)
|
|
{
|
|
dicEditCellState[kv.Key] = kv.Value;
|
|
}
|
|
|
|
#region 设置格子颜色
|
|
foreach (Cell cell in GridSystem.cells)
|
|
{
|
|
if (!TryGetCellStateByIndex(cell.index, out E_CampCellState cellState))
|
|
continue;
|
|
|
|
SetCellColorByCellState(cell, cellState);
|
|
}
|
|
#endregion
|
|
|
|
IsShowAllGrid = true;
|
|
|
|
IsEdit = true;
|
|
}
|
|
|
|
public void UpdateEdit()
|
|
{
|
|
if (!IsDrag)
|
|
return;
|
|
|
|
ClearDragCell(); // 还原拖动的格子
|
|
SetDragCell();
|
|
}
|
|
|
|
/// <summary>
|
|
/// 退出编辑模式
|
|
/// </summary>
|
|
public void ExitEdit()
|
|
{
|
|
if (!IsEdit)
|
|
return;
|
|
|
|
IsShowAllGrid = false;
|
|
|
|
dicEditCellState.Clear();
|
|
|
|
foreach (CampUnitBase unit in setEditUnit)
|
|
{
|
|
unit.Dispose();
|
|
}
|
|
setEditUnit.Clear();
|
|
|
|
if (null != buildingCampUnit)
|
|
{
|
|
buildingCampUnit.Dispose();
|
|
buildingCampUnit = null;
|
|
}
|
|
|
|
setCellDrag.Clear();
|
|
|
|
IsEdit = false;
|
|
}
|
|
|
|
/// <summary>
|
|
/// 进入拖动状态
|
|
/// </summary>
|
|
public async void EnterDrag(DataCampObject dataCampObject)
|
|
{
|
|
if (IsDrag)
|
|
return;
|
|
|
|
GameObject goCampObject = await LoadCampObject(dataCampObject.Path);
|
|
buildingCampUnit = new(goCampObject, dataCampObject);
|
|
|
|
IsDrag = true;
|
|
}
|
|
|
|
public void ExitDrag()
|
|
{
|
|
if (!IsDrag)
|
|
return;
|
|
|
|
IsDrag = false;
|
|
|
|
if (!EditCheckPlace(buildingCampUnit.CellIndex, buildingCampUnit.Cfg.ListPosOffset))
|
|
{
|
|
UITipsManager.ShowTips("该位置不能放置");
|
|
buildingCampUnit.Dispose();
|
|
}
|
|
else
|
|
EditPlaceCampItem();
|
|
|
|
buildingCampUnit = null;
|
|
|
|
ClearDragCell();
|
|
}
|
|
|
|
/// <summary>
|
|
/// 清除拖动的格子
|
|
/// </summary>
|
|
private void ClearDragCell()
|
|
{
|
|
foreach (Cell cell in setCellDrag)
|
|
{
|
|
if (dicEditCellState.TryGetValue(cell.index, out E_CampCellState cellState))
|
|
SetCellColorByCellState(cell, cellState);
|
|
}
|
|
|
|
setCellDrag.Clear();
|
|
}
|
|
|
|
/// <summary>
|
|
/// 设置拖动建筑影响的格子
|
|
/// </summary>
|
|
private void SetDragCell()
|
|
{
|
|
Vector2 mousePos = Mouse.current.position.ReadValue();
|
|
// 发射射线
|
|
Ray ray = CameraManager.Instance.MainCamera.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 (null == centerCell)
|
|
{
|
|
buildingCampUnit.CellIndex = -1;
|
|
buildingCampUnit.SetPos(new Vector3(firstHit.point.x, 0f, firstHit.point.z));
|
|
return;
|
|
}
|
|
|
|
foreach (Vector2 offset in buildingCampUnit.Cfg.ListPosOffset)
|
|
{
|
|
Vector2Int newPosInt = new(centerCell.row + (int)offset.x, centerCell.column + (int)offset.y);
|
|
if (!TryGetCellByRowCol(newPosInt, out Cell cell))
|
|
continue;
|
|
|
|
setCellDrag.Add(cell);
|
|
SetDragStateColor(cell);
|
|
|
|
if (Vector2Int.zero == offset)
|
|
{
|
|
buildingCampUnit.CellIndex = cell.index;
|
|
Vector3 pos = GridSystem.CellGetPosition(cell);
|
|
buildingCampUnit.SetPos(new Vector3(pos.x, 0f, pos.z));
|
|
}
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// 设置拖动状态的颜色
|
|
/// </summary>
|
|
/// <param name="cell"></param>
|
|
private void SetDragStateColor(Cell cell)
|
|
{
|
|
if (!dicEditCellState.TryGetValue(cell.index, out E_CampCellState cellState))
|
|
return;
|
|
|
|
E_CampCellState tempState = cellState switch
|
|
{
|
|
E_CampCellState.Empty => E_CampCellState.Valid,
|
|
E_CampCellState.Occupancy => E_CampCellState.Invalid,
|
|
_ => throw new System.NotImplementedException(),
|
|
};
|
|
SetCellColorByCellState(cell, tempState);
|
|
}
|
|
|
|
/// <summary>
|
|
/// 编辑检查能否放置
|
|
/// </summary>
|
|
/// <returns></returns>
|
|
private bool EditCheckPlace(int cellIndex, params Vector2[] offsets)
|
|
{
|
|
if (!TryGetCellByIndex(cellIndex, out Cell centerCell))
|
|
return false;
|
|
|
|
foreach (Vector2 offset in offsets)
|
|
{
|
|
Vector2Int cellPos = new(centerCell.row + (int)offset.x, centerCell.column + (int)offset.y); // 计算格子位置
|
|
if (!dicCellByRowCol.TryGetValue(cellPos, out Cell cell))
|
|
return false;
|
|
|
|
if (!dicEditCellState.TryGetValue(cell.index, out E_CampCellState cellState))
|
|
return false;
|
|
|
|
if (E_CampCellState.Empty != cellState)
|
|
return false;
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
/// <summary>
|
|
/// 编辑下放置营地物件
|
|
/// </summary>
|
|
/// <param name="goCampObject"></param>
|
|
/// <param name="gridIndex"></param>
|
|
private void EditPlaceCampItem()
|
|
{
|
|
#region 设置营地地板状态
|
|
if (!dicCellByIndex.TryGetValue(buildingCampUnit.CellIndex, out Cell centerCell))
|
|
return;
|
|
|
|
foreach (Vector2 offset in buildingCampUnit.Cfg.ListPosOffset)
|
|
{
|
|
Vector2Int gridPos = new(centerCell.row + (int)offset.x, centerCell.column + (int)offset.y); // 计算格子位置
|
|
if (!dicCellByRowCol.TryGetValue(gridPos, out Cell cell))
|
|
continue;
|
|
|
|
if (dicEditCellState.ContainsKey(cell.index))
|
|
dicEditCellState[cell.index] = E_CampCellState.Occupancy;
|
|
}
|
|
#endregion
|
|
|
|
Vector3 pos = GridSystem.CellGetPosition(centerCell.index);
|
|
buildingCampUnit.SetPos(new Vector3(pos.x, 0f, pos.z)); // 设置建筑物位置
|
|
|
|
setEditUnit.Add(buildingCampUnit);
|
|
}
|
|
}
|
|
} |