Skip to Content
DocsWayfinderGrid System

Grid System

Wayfinder’s grid system handles tile management, pathfinding, range calculation, and height-based mechanics for isometric tactical combat.

Core Components

Tile

Represents a single grid tile in the battle map.

public class Tile : MonoBehaviour { public Vector3Int gridLocation; // 3D grid position (x, y, z) public Vector2Int grid2DLocation; // 2D position (x, y) public float height; // Visual height of tile public UnitStateManager currentUnit; // Unit occupying this tile public TileStatus status; // Passable, Blocked, InAbilityRange, InAoEPattern }

Key Properties:

  • gridLocation - Full 3D position including height (Z-axis)
  • grid2DLocation - 2D position for pathfinding (X, Y only)
  • height - Visual height for rendering
  • currentUnit - Which unit is on this tile (null if empty)

TileManager

Manages the grid tilemap and provides tile lookup/neighbor finding.

public class TileManager : MonoBehaviour { public Dictionary<Vector2Int, Tile> map; // All tiles by 2D position public Tile GetAdjacentTile(Tile currentTile, int xDiff, int yDiff); public List<Tile> GetNeighborTiles(Tile currentTile, Unit unit, List<Tile> searchableTiles, bool ignoreHeight); public Tile GetUnitCurrentTile(UnitStateManager unit); }

Methods:

  • GetNeighborTiles - Returns valid adjacent tiles for pathfinding
  • GetAdjacentTile - Gets tile at offset position
  • GetUnitCurrentTile - Finds which tile a unit is on

Pathfinding

Pathfinder Class

A* pathfinding with tactical RPG movement rules.

public class Pathfinder { public List<Tile> FindPath(TileManager tileManager, Unit unit, Tile start, Tile end, List<Tile> searchableTiles, bool ignoreHeight, int minRange = 0); public int GetPathDistance(TileManager tileManager, Unit unit, Tile start, Tile end, bool ignoreHeight); public bool IsTileWithinAbilityRange(Unit currentUnit, Unit targetUnit, Ability ability); }

Movement Rules:

  • Units can pass through allies but not end movement on occupied tiles
  • Units cannot pass through enemies
  • Height differences limited by unit.jumpUp and unit.jumpDown
  • Pathfinding uses Manhattan distance heuristic

Example: Find Path

Pathfinder pathfinder = new Pathfinder(); TileManager tileManager = BattleStateManager.Instance.tileManager; List<Tile> path = pathfinder.FindPath( tileManager, unit, // Unit moving startTile, // Current position endTile, // Destination new List<Tile>(), // Empty = search all tiles false // Don't ignore height ); if (path.Count > 0) { // Move along path foreach (Tile tile in path) { // Move to tile.transform.position } }

Height Mechanics

Units have jump capabilities:

public int jumpUp; // Max tiles can jump UP public int jumpDown; // Max tiles can jump DOWN

Example:

  • Knight: jumpUp = 2, jumpDown = 3
  • Can jump from ground to 2-tile-high platform
  • Can drop from 3-tile-high cliff to ground
  • Cannot reach 3-tile-high platform without stairs

Height in Abilities:

public int MaxVerticalRange; // Max height difference for ability public bool ignoresHeight; // Ability ignores height restrictions

Range Calculation

Range Class

Calculates movement and ability range.

public class Range { public List<Tile> GetTilesWithinRange(Tile fromTile, int minRange, int maxRange, Unit unit, bool ignoreHeight); public List<Tile> GetReachableTiles(Tile fromTile, int minRange, int maxRange, Unit unit, bool ignoreHeight); }

Two Methods:

  1. GetTilesWithinRange - Fast expansion-based range (ignores obstacles)
  2. GetReachableTiles - Accurate pathfinding-based range (respects obstacles)

When to Use:

  • GetTilesWithinRange: Ability range (magic can target through walls)
  • GetReachableTiles: Movement range (units must path around obstacles)

Example: Movement Range

Range range = new Range(); List<Tile> moveTiles = range.GetReachableTiles( unit.currentTile, 1, // Min range (must move at least 1 tile) unit.move, // Max range (unit's movement stat) unit, false // Respect height ); // Show blue overlay on moveTiles foreach (Tile tile in moveTiles) { tile.Show(); tile.SetStatus(Tile.TileStatus.Passable); }

Example: Ability Range

Range range = new Range(); List<Tile> abilityTiles = range.GetTilesWithinRange( unit.currentTile, ability.GetMinRange(unit), ability.GetMaxRange(unit), unit, ability.ignoresHeight ); // Show yellow overlay on abilityTiles foreach (Tile tile in abilityTiles) { tile.Show(); tile.SetStatus(Tile.TileStatus.InAbilityRange); }

Grid Setup

Creating the Grid

  1. Create Tilemap

    • Right-click Hierarchy > 2D Object > Tilemap > Rectangular
    • This creates Grid with Tilemap child
  2. Paint Tiles

    • Window > 2D > Tile Palette
    • Create tiles and paint your battle grid
  3. Add Height

    • Paint on different Z-levels for elevation
    • Z=0: Ground level
    • Z=1: 1-tile elevation
    • Z=2: 2-tile elevation
  4. Add TileManager

    • Create empty GameObject named Tile Manager
    • Add TileManager component
    • Assign Tilemap reference
    • Assign Tile Prefab (provided by Wayfinder)

Example Tilemap Structure

Grid (GameObject) ├── Layer: Z=0 (Ground) │ └── Tiles: Floor tiles ├── Layer: Z=1 (Elevation +1) │ └── Tiles: Raised platforms └── Layer: Z=2 (Elevation +2) └── Tiles: High cliffs

Performance Tips

Pathfinding Optimization

Wayfinder’s pathfinding is efficient, but for large maps:

Limit search space:

// Only search within movement range List<Tile> searchSpace = GetTilesWithinRange(start, 0, unit.move + 5, unit, false); List<Tile> path = pathfinder.FindPath(tileManager, unit, start, end, searchSpace, false);

Cache paths:

// Cache AI pathfinding results Dictionary<(Tile, Tile), List<Tile>> pathCache = new Dictionary<(Tile, Tile), List<Tile>>();

Tile Lookup Optimization

TileManager uses Dictionary<Vector2Int, Tile> for O(1) tile lookups:

// Fast lookup Tile tile = tileManager.map[new Vector2Int(x, y)]; // Check if tile exists if (tileManager.map.ContainsKey(new Vector2Int(x, y))) { Tile tile = tileManager.map[new Vector2Int(x, y)]; }

Next Steps

Last updated on