UnityUtils icon indicating copy to clipboard operation
UnityUtils copied to clipboard

Change A* implementation to use a Grid interface

Open buddhisthead opened this issue 6 years ago • 0 comments

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;
    }

buddhisthead avatar Oct 11 '19 18:10 buddhisthead