96 lines
3.7 KiB
C#
96 lines
3.7 KiB
C#
using UnityEngine;
|
|
|
|
namespace AibisDream
|
|
{
|
|
public static class BlockPuzzleGridEx
|
|
{
|
|
public static SnapResult CheckSnapToGrid(this IBlockPuzzleGrid grid, BlockShape shape)
|
|
{
|
|
// 预制错误结果作为返回值
|
|
SnapResult result = new SnapResult
|
|
{
|
|
canSnap = false,
|
|
snapPosition = shape.transform.position,
|
|
gridX = 0,
|
|
gridY = 0,
|
|
distance = float.MaxValue,
|
|
gridPositions = new Vector2Int[0]
|
|
};
|
|
|
|
// 将Shape的世界坐标转换为网格坐标(可以是虚拟坐标)
|
|
bool inGrid = grid.WorldToGrid(shape.transform.position, out int gridX, out int gridY);
|
|
if (!inGrid) return result;
|
|
|
|
// 将形状的所有格子转换为网格坐标
|
|
// gridX, gridY 是形状的 (0, 0) 点在网格中的位置
|
|
Vector2Int[] gridCells = ConvertShapeToGridCells(shape, gridX, gridY);
|
|
result.gridX = gridX;
|
|
result.gridY = gridY;
|
|
result.snapPosition = grid.GridToWorld(gridX, gridY);
|
|
result.gridPositions = gridCells;
|
|
|
|
// 逐个坐标验证是否可以放置
|
|
var canPlace = grid.CanPlace(gridCells);
|
|
if (!canPlace) return result;
|
|
result.canSnap = true;
|
|
result.distance = Vector3.Distance(shape.transform.position, result.snapPosition);
|
|
|
|
return result;
|
|
}
|
|
|
|
/// <summary>
|
|
/// 将形状的相对坐标转换为网格坐标
|
|
/// 已知形状的 (0, 0) 点在网格中的位置为 (gridX, gridY),将形状的其他格子坐标转换为网格坐标
|
|
/// </summary>
|
|
/// <param name="shape">形状</param>
|
|
/// <param name="gridX">网格X坐标(形状左下角位置,即形状的 (0, 0) 点对应的网格坐标)</param>
|
|
/// <param name="gridY">网格Y坐标(形状左下角位置,即形状的 (0, 0) 点对应的网格坐标)</param>
|
|
/// <returns>形状所有格子在网格中的坐标数组</returns>
|
|
public static Vector2Int[] ConvertShapeToGridCells(IBlockShape shape, int gridX, int gridY)
|
|
{
|
|
if (shape == null)
|
|
{
|
|
return new Vector2Int[0];
|
|
}
|
|
|
|
Vector2Int[] blockPositions = shape.GetBlockPositions();
|
|
if (blockPositions == null || blockPositions.Length == 0)
|
|
{
|
|
return new Vector2Int[0];
|
|
}
|
|
|
|
Vector2Int[] gridCells = new Vector2Int[blockPositions.Length];
|
|
|
|
for (int i = 0; i < blockPositions.Length; i++)
|
|
{
|
|
// 将形状的相对坐标转换为网格坐标
|
|
// 形状的 (0, 0) 对应网格的 (gridX, gridY)
|
|
// 形状的 (blockPos.x, blockPos.y) 对应网格的 (gridX + blockPos.x, gridY + blockPos.y)
|
|
gridCells[i] = new Vector2Int(
|
|
gridX + blockPositions[i].x,
|
|
gridY + blockPositions[i].y
|
|
);
|
|
}
|
|
|
|
return gridCells;
|
|
}
|
|
|
|
/// <summary>
|
|
/// 为吸附制作预览
|
|
/// </summary>
|
|
/// <param name="shapeCells">转换后的网格坐标组</param>
|
|
public static void ShowSnapPreview(this IBlockPuzzleGrid grid, Vector2Int[] shapeCells)
|
|
{
|
|
|
|
}
|
|
|
|
public static void TrySnapToGrid(this IBlockPuzzleGrid grid, BlockShape shape, Vector2Int rootCell)
|
|
{
|
|
// 判断RootCell的位置
|
|
var rootWorldPos = grid.GridToWorld(rootCell.x, rootCell.y);
|
|
// 已经判断是否可吸附,直接吸就好了
|
|
shape.transform.position = rootWorldPos;
|
|
// TODO: 设置网格状态
|
|
}
|
|
}
|
|
} |