Pathfinding icon indicating copy to clipboard operation
Pathfinding copied to clipboard

Find path to direct neighbour

Open codevogel opened this issue 6 years ago • 3 comments

It could be that you left this out for optimisation reasons, seeing as you could easily implement a way to check if one of the neighbours is your target tile before even calling the regular algorithm,

But the algorithms implementation (at least after episode 5) cannot find the path to it's direct neighbour.

Here's a proposed fix:

// in Pathfinding.cs

// in
    Vector3[] SimplifyPath(List<Tile> path)
    {
        List<Vector3> waypoints = new List<Vector3>();
        Vector2 directionOld = Vector2.zero;

        // ***************
        // Add this to make sure we do not just ignore the case where path.Count == 1
        // before even checking the rest
        //  **************
        if (path.Count == 1)
        {
            waypoints.Add(path[0].worldPos);
            return waypoints.ToArray();
        }

        for (int i = 1; i < path.Count; i++)
        {
            Vector2 directionNew = new Vector2(path[i - 1].gridCoords.x - path[i].gridCoords.x,
                                               path[i - 1].gridCoords.y - path[i].gridCoords.y);
            if (directionNew != directionOld)
            {
                // Also of importance: 
                // We start at i = 1, but we need to check all the way to the origin! so [i-1]
                waypoints.Add(path[i-1].worldPos);
            }
            directionOld = directionNew;
        }
        return waypoints.ToArray();
    }

codevogel avatar Apr 02 '19 23:04 codevogel

There is a bug in the code, as pointed out by user DMGregory on Gamedev.Stackexchange:

In file Node.cs,

return gCost = hCost;

should be

return gCost + hCost;

Fixing this bug in the code could get the rest of the code to work, so the solution you propose might not be needed.

vaillancourt avatar Sep 13 '19 13:09 vaillancourt

It could be that you left this out for optimisation reasons, seeing as you could easily implement a way to check if one of the neighbours is your target tile before even calling the regular algorithm,

But the algorithms implementation (at least after episode 5) cannot find the path to it's direct neighbour.

Here's a proposed fix:

// in Pathfinding.cs

// in
    Vector3[] SimplifyPath(List<Tile> path)
    {
        List<Vector3> waypoints = new List<Vector3>();
        Vector2 directionOld = Vector2.zero;

        // ***************
        // Add this to make sure we do not just ignore the case where path.Count == 1
        // before even checking the rest
        //  **************
        if (path.Count == 1)
        {
            waypoints.Add(path[0].worldPos);
            return waypoints.ToArray();
        }

        for (int i = 1; i < path.Count; i++)
        {
            Vector2 directionNew = new Vector2(path[i - 1].gridCoords.x - path[i].gridCoords.x,
                                               path[i - 1].gridCoords.y - path[i].gridCoords.y);
            if (directionNew != directionOld)
            {
                // Also of importance: 
                // We start at i = 1, but we need to check all the way to the origin! so [i-1]
                waypoints.Add(path[i-1].worldPos);
            }
            directionOld = directionNew;
        }
        return waypoints.ToArray();
    }

thx.

Blaxor avatar Dec 20 '20 19:12 Blaxor

Complementing the suggested topic optimization, add the commented line after the while loop:

	// In Pathfinding.cs:
	
	Vector3[] RetracePath(Node startNode, Node endNode) {
		
		List<Node> path = new List<Node>();
		Node currentNode = endNode;
		
		while (currentNode != startNode) {
			path.Add(currentNode);
			currentNode = currentNode.parent;
		}
		
		path.Add(currentNode); // Be sure to add this line, or the nearest neighbour will be skipped;

		Vector3[] waypoints = SimplifyPath(path);
		Array.Reverse(waypoints);

		grid.path = path;
		return waypoints;
	}

ghost avatar Feb 16 '22 17:02 ghost