Use case: I can build a path and draw it with line renderer, and then I want to be able to drag a single node in the path and move it elsewhere.
So I want to be able to know if the new path with the moved node is still valid or not, in order to make sure it doesn’t go behind an obstacle for example.
After reading the docs, I see there could be two approaches:
calling FloodFill and UpdateGraphs passing the new position of the node with an GraphUpdateObject object.
using PathUtilities.IsPathPossible. (Shouldn’t FloodFill / UpdateGraphs need to be called in this case as well?)
Which one is the correct/best of the two in this case?
var node1 = AstarPath.active.GetNearest(...).node;
var node2 = AstarPath.active.GetNearest(...).node;
bool possible = PathUtilities.IsPathPossible(node1, node2);
Normally the data that the IsPathPossible method uses should be up to date. The only case where you would need to flood fill the graph first would be if you have done modifications to the graph in some very non-standard way (like using GraphUpdateObjects) which doesn’t automatically do that.
One last thing: after moving the node and using PathUtilities.IsPathPossible, what do I need to do to check the length of the path, besides calling path.GetTotalLength()? I believe I DO have to call FloodFill first in that case, right?
Otherwise the path.GetTotalLength() will return the length of the path before the node was moved, right?
I’m not quite sure how you are updating the graph, so I cannot say really.
However if you want to recalculate the length then you need to calculate a new path, you cannot reuse the old one as it may no longer correspond to the shortest path in the modified graph.
I actually don’t want to calculate a new path since the idea is for the player to be able to move a node, but keeping the rest of the path unaltered. It doesn’t matter if the resulting path is not the shortest.
If there are no options without re-calculating the path, I’ll calculate the distances between nodes manually and add them up.
Ok. If you just want to move a single point in the path, then you should probably just modify the vectorPath list on the path object. The GetTotalLength method just calculates the total length of that polyline.
/** Total Length of the path.
* Calculates the total length of the #vectorPath.
* Cache this rather than call this function every time since it will calculate the length every time, not just return a cached value.
* \returns Total length of #vectorPath, if #vectorPath is null positive infinity is returned.
*/
public float GetTotalLength () {
if (vectorPath == null) return float.PositiveInfinity;
float tot = 0;
for (int i = 0; i < vectorPath.Count-1; i++) tot += Vector3.Distance(vectorPath[i], vectorPath[i+1]);
return tot;
}
I tried using PathUtilities.IsPathPossible but unfortunately doesn’t work for my use case.
Probably I didn’t explain it correctly or not with enough information.
The idea I had in mind is that if I move one node of the path behind an obstacle, the path should turn out to be an invalid one, like in the image below:
But just realized that PathUtilities.IsPathPossible says that the path is valid if both nodes are walkable and in the same area, which makes complete sense. But I thought that if an obstacle was in the middle of two nodes it would say the path is invalid.
I don’t want the new shortest path to be found, but I rather I want to keep the same path with the node in the middle moved and Astar telling me that the new path is invalid since the node is behind an obstacle.
Is this even possible?