UnityUtils
UnityUtils copied to clipboard
Change A* implementation to use a Grid interface
Here is a small change to support existing games and non-square grids (namely, hexes). It also allows very large "grid" systems that can't store their costs in a static array. For example, I am building an open world editing tool, which stores a sparse representation of a hex "grid"; using the Grid array would be force eager evaluation of the entire world. This PR allows a lazy fetch of Nodes and also the concrete Neighbors can return hex directions instead of just orthogonal ones. For hexes, the implementation can convert to "offset" coordinates and still use x,y indexing in the existing library.
Here is a copy of my lazy hexes implementation...
//==========================================================
// Implement the GridI interface for A* pathfinding library
//==========================================================
// Node cache
Dictionary<(int, int), Node> NodeCache;
public void PrepareForPathFinding(Pathfinding.DistanceType distance)
{
NodeCache = new Dictionary<(int, int), Node> ();
}
public Node GetNode (int x, int y)
{
Node node = null;
// Lookup node in cache
NodeCache.TryGetValue ((x, y), out node);
if (node == null) {
// Not there. Create a new one with tile cost based on terrain type, otherw
TileValue tileValue = overworldMap.GetTileValue (x, y);
node = new Node (true, x, y); // default cost = 1.0
if (tileValue.Type == TileType.TTerrain) {
TerrainType tt = (TerrainType)tileValue.Value;
SpriteMapItem spriteItem = TerrainTileSetProvider.getSpriteItem (tt.group, tt.index);
if (spriteItem != null) {
node.price = spriteItem.cost;
}
}
// Put new node in cache
NodeCache.Add ((x, y), node);
}
return node;
}
public IEnumerable<Node> GetNeighbours (Node currentNode, Pathfinding.DistanceType distance)
{
Hex hex = new Hex (currentNode.gridX, currentNode.gridY);
List<Hex> spaces = hex.Neighbors (1);
foreach (Hex space in spaces) {
Node node = GetNode(space.col, space.row);
yield return node;
}
yield return null;
}