Pathfinding
Pathfinding copied to clipboard
Find path to direct neighbour
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();
}
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.
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.
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;
}