Adding Grid Coordinates System, and a testScript
This commit is contained in:
parent
3cd4bada37
commit
0ed4df8bc9
7 changed files with 792 additions and 0 deletions
140
Assets/_Project/Scripts/Core/GridCoordinates.cs
Normal file
140
Assets/_Project/Scripts/Core/GridCoordinates.cs
Normal file
|
|
@ -0,0 +1,140 @@
|
|||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
|
||||
namespace TD.Core
|
||||
{
|
||||
/// <summary>
|
||||
/// Pure math utility for converting between tile-grid coordinates and world-space
|
||||
/// coordinates, plus common grid helpers (neighbors, distance, adjacency).
|
||||
///
|
||||
/// This class knows nothing about maps, walkability, zones, or game state. It only
|
||||
/// answers: "where in the world is tile (x, y)?" and "what tile contains world point P?"
|
||||
///
|
||||
/// Conventions:
|
||||
/// - Tiles are 1.0 world unit on each side (TILE_SIZE).
|
||||
/// - Tiles are CENTER-BASED: tile (0, 0) has its center at world (0, 0, 0)
|
||||
/// and occupies world XZ from (-0.5, -0.5) to (+0.5, +0.5).
|
||||
/// - The grid lives on the XZ plane at Y = BUILDABLE_PLANE_Y. Grid-y maps to world-z.
|
||||
/// - 4-connected (no diagonals).
|
||||
/// </summary>
|
||||
public static class GridCoordinates
|
||||
{
|
||||
// ----- Constants -----------------------------------------------------------
|
||||
|
||||
/// <summary>World units per tile edge. Single source of truth for tile sizing.</summary>
|
||||
public const float TILE_SIZE = 1.0f;
|
||||
|
||||
/// <summary>Y coordinate of the buildable plane in world space.</summary>
|
||||
public const float BUILDABLE_PLANE_Y = 0.0f;
|
||||
|
||||
// ----- Core conversions ----------------------------------------------------
|
||||
|
||||
/// <summary>
|
||||
/// Returns the world-space center of the given tile, on the buildable plane.
|
||||
/// Use this for placing towers, drawing ghost previews, and for A* path waypoints.
|
||||
/// </summary>
|
||||
public static Vector3 GridToWorld(Vector2Int gridPos)
|
||||
{
|
||||
return new Vector3(
|
||||
gridPos.x * TILE_SIZE,
|
||||
BUILDABLE_PLANE_Y,
|
||||
gridPos.y * TILE_SIZE);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns the tile that contains the given world position.
|
||||
/// The Y component of worldPos is ignored. Uses round-to-nearest because
|
||||
/// tiles are center-based — any world point within ±0.5 of a tile's center
|
||||
/// belongs to that tile.
|
||||
/// </summary>
|
||||
public static Vector2Int WorldToGrid(Vector3 worldPos)
|
||||
{
|
||||
return new Vector2Int(
|
||||
Mathf.RoundToInt(worldPos.x / TILE_SIZE),
|
||||
Mathf.RoundToInt(worldPos.z / TILE_SIZE));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Overload for callers that already have a 2D XZ position (e.g., UI raycast hits
|
||||
/// projected onto the buildable plane).
|
||||
/// </summary>
|
||||
public static Vector2Int WorldToGrid(Vector2 worldPosXZ)
|
||||
{
|
||||
return new Vector2Int(
|
||||
Mathf.RoundToInt(worldPosXZ.x / TILE_SIZE),
|
||||
Mathf.RoundToInt(worldPosXZ.y / TILE_SIZE));
|
||||
}
|
||||
|
||||
// ----- Grid helpers --------------------------------------------------------
|
||||
|
||||
/// <summary>
|
||||
/// True if two tiles share an edge (4-connected). Diagonal neighbors return false.
|
||||
/// </summary>
|
||||
public static bool IsAdjacent(Vector2Int a, Vector2Int b)
|
||||
{
|
||||
int dx = Mathf.Abs(a.x - b.x);
|
||||
int dy = Mathf.Abs(a.y - b.y);
|
||||
return (dx + dy) == 1;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Manhattan distance between two tiles. This is the natural admissible
|
||||
/// heuristic for A* on a 4-connected grid with uniform step cost.
|
||||
/// </summary>
|
||||
public static int ManhattanDistance(Vector2Int a, Vector2Int b)
|
||||
{
|
||||
return Mathf.Abs(a.x - b.x) + Mathf.Abs(a.y - b.y);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Yields the four cardinal neighbors of the given tile (N, E, S, W).
|
||||
/// Does NOT check walkability or map bounds — that is the caller's job.
|
||||
/// </summary>
|
||||
public static IEnumerable<Vector2Int> GetNeighbors(Vector2Int tile)
|
||||
{
|
||||
yield return new Vector2Int(tile.x, tile.y + 1); // North (+z)
|
||||
yield return new Vector2Int(tile.x + 1, tile.y); // East (+x)
|
||||
yield return new Vector2Int(tile.x, tile.y - 1); // South (-z)
|
||||
yield return new Vector2Int(tile.x - 1, tile.y); // West (-x)
|
||||
}
|
||||
|
||||
// ----- Footprint helpers ---------------------------------------------------
|
||||
//
|
||||
// Towers occupy a footprint of N x M tiles anchored at a single tile coordinate.
|
||||
// The anchor is the SOUTHWEST (minimum-x, minimum-y) corner of the footprint.
|
||||
// For a 2x2 tower at anchor (5, 7), the footprint covers:
|
||||
// (5, 7), (6, 7), (5, 8), (6, 8)
|
||||
|
||||
/// <summary>
|
||||
/// Yields every tile covered by a footprint of the given size, anchored
|
||||
/// at the given tile (anchor is the southwest corner of the footprint).
|
||||
/// </summary>
|
||||
public static IEnumerable<Vector2Int> GetFootprintTiles(Vector2Int anchor, Vector2Int footprintSize)
|
||||
{
|
||||
for (int dx = 0; dx < footprintSize.x; dx++)
|
||||
{
|
||||
for (int dy = 0; dy < footprintSize.y; dy++)
|
||||
{
|
||||
yield return new Vector2Int(anchor.x + dx, anchor.y + dy);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns the world-space center of a footprint anchored at the given tile.
|
||||
/// For a 2x2 footprint at anchor (5, 7) with TILE_SIZE = 1.0, returns (5.5, 0, 7.5).
|
||||
/// Use this to position the tower's visual GameObject so it sits centered on its
|
||||
/// footprint rather than on the anchor tile's center.
|
||||
/// </summary>
|
||||
public static Vector3 GetFootprintCenterWorld(Vector2Int anchor, Vector2Int footprintSize)
|
||||
{
|
||||
float centerOffsetX = (footprintSize.x - 1) * 0.5f * TILE_SIZE;
|
||||
float centerOffsetZ = (footprintSize.y - 1) * 0.5f * TILE_SIZE;
|
||||
Vector3 anchorWorld = GridToWorld(anchor);
|
||||
return new Vector3(
|
||||
anchorWorld.x + centerOffsetX,
|
||||
anchorWorld.y,
|
||||
anchorWorld.z + centerOffsetZ);
|
||||
}
|
||||
}
|
||||
}
|
||||
2
Assets/_Project/Scripts/Core/GridCoordinates.cs.meta
Normal file
2
Assets/_Project/Scripts/Core/GridCoordinates.cs.meta
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 55f1a840195c0684786a2ddcf30d5865
|
||||
12
Assets/_Project/Scripts/Core/_testScript.cs
Normal file
12
Assets/_Project/Scripts/Core/_testScript.cs
Normal file
|
|
@ -0,0 +1,12 @@
|
|||
using UnityEngine;
|
||||
using TD.Core;
|
||||
|
||||
public class GridCoordsTest : MonoBehaviour
|
||||
{
|
||||
void Start()
|
||||
{
|
||||
Debug.Log($"Tile (5,7) world center: {GridCoordinates.GridToWorld(new Vector2Int(5, 7))}");
|
||||
Debug.Log($"World (5.3, 0, 6.8) maps to tile: {GridCoordinates.WorldToGrid(new Vector3(5.3f, 0, 6.8f))}");
|
||||
Debug.Log($"2x2 footprint at (5,7) center: {GridCoordinates.GetFootprintCenterWorld(new Vector2Int(5, 7), new Vector2Int(2, 2))}");
|
||||
}
|
||||
}
|
||||
2
Assets/_Project/Scripts/Core/_testScript.cs.meta
Normal file
2
Assets/_Project/Scripts/Core/_testScript.cs.meta
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 9c2af3b2731bd314e8502ac9db3a8bc5
|
||||
Loading…
Add table
Add a link
Reference in a new issue