Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

Improving A* path finding efficiency in a 2D Grid based Unity game

public List<Node> FindPath(Vector2Int start, Vector2Int target)
{
    List<Node> openSet = new List<Node>();
    HashSet<Node> closedSet = new HashSet<Node>();
    Node startNode = grid.GetNode(start);
    Node targetNode = grid.GetNode(target);

    openSet.Add(startNode);

    while (openSet.Count > 0)
    {
        Node currentNode = openSet[0];
        for (int i = 1; i < openSet.Count; i++)
        {
            if (openSet[i].FCost < currentNode.FCost || (openSet[i].FCost == currentNode.FCost && openSet[i].HCost < currentNode.HCost))
            {
                currentNode = openSet[i];
            }
        }

        openSet.Remove(currentNode);
        closedSet.Add(currentNode);

        if (currentNode == targetNode)
        {
            return RetracePath(startNode, targetNode);
        }

        foreach (Node neighbor in grid.GetNeighbors(currentNode))
        {
            if (!neighbor.Walkable || closedSet.Contains(neighbor))
            {
                continue;
            }

            int newMovementCostToNeighbor = currentNode.GCost + GetDistance(currentNode, neighbor);
            if (newMovementCostToNeighbor < neighbor.GCost || !openSet.Contains(neighbor))
            {
                neighbor.GCost = newMovementCostToNeighbor;
                neighbor.HCost = GetDistance(neighbor, targetNode);
                neighbor.Parent = currentNode;

                if (!openSet.Contains(neighbor))
                {
                    openSet.Add(neighbor);
                }
            }
        }
    }

    return null;
}

int GetDistance(Node nodeA, Node nodeB)
{
    int dstX = Mathf.Abs(nodeA.GridX - nodeB.GridX);
    int dstY = Mathf.Abs(nodeA.GridY - nodeB.GridY);
    return dstX + dstY;
}

List<Node> RetracePath(Node startNode, Node endNode)
{
    List<Node> path = new List<Node>();
    Node currentNode = endNode;

    while (currentNode != startNode)
    {
        path.Add(currentNode);
        currentNode = currentNode.Parent;
    }
    path.Reverse();
    return path;
}

A* algorithm is computionally expensive, grid size add more complexity, the game environment should change dynamically.

I tried path catching, simplifying grid and multi-threading to improvise, still can’t make a significant improvement. Kindly just give your advice to improve the game system.

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

>Solution :

Try concise tracking in grid. That can improve the performance a lot.

Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading