Hi,
I need to get the nearest Node with a specific tag, that is reachable from a start position. The point is, to get the nearest water spot to drink out of a river. I am using a grid graph and I tag the Nodes that are in water with a specific tag.
My current approach works, but not consistently. It often gives me unreachable nodes (also I think this approach is really not efficient):
`bool MoveToNearestWaterspot ()
{
waterSpot = new GameObject("waterspot").transform;
NNConstraint consWater = new NNConstraint();
consWater.constrainTags = true;
consWater.tags = 100;
consWater.constrainWalkability = false;
NNConstraint consByWater = new NNConstraint();
consByWater.constrainTags = false;
consByWater.constrainWalkability = true;
NNInfo waterNode = graph.GetNearestForce(root.transform.position, consWater);
if (waterNode.node == null)
return false;
waterSpot.position = new Vector3(waterNode.node.position.x / 1000, waterNode.node.position.y / 1000, waterNode.node.position.z / 1000);
NNInfo byWaterNode = graph.GetNearestForce(waterSpot.position, consByWater);
waterSpot.position = new Vector3(byWaterNode.node.position.x / 1000, byWaterNode.node.position.y / 1000, byWaterNode.node.position.z / 1000);
return true;
}`
Hi
Sorry for the late answer.
You can constrain it to only search in a specific connected component of the graph.
Something like:
`
consWater.constrainArea = true;
// Set the area it should constrain the search to
// This will constrain it to all regions reachable by the player
consWater.area = AstarPath.active.GetNearest (playerPosition, NNConstraint.Default).node.area;
// + the rest of the settings you had
AstarPath.active.GetNearest (somePosition, consWater);
`
Q: How do I get the shortest walkable path from a known position to any node-position with a specific tag?
Explanation:
Hey, I want to revive this topic, as I need to specify this even more.
This behaves well, but it still needs an optimization. Because: I find the nearest point tagged “water” to the player position. But that is not necessarily the shortest path, if there is e.g. an unwalkable area between the player position and the nearest water position.
I want to find the shortest path to any water position reachable by the player.
I tried out a lot, but can’t seem to get the hang of how to achieve this. Maybe someone has already achieved this or has an idea?
Hi
You can do that with the MultiTargetPath, however since the number of nodes with a specific tag is probably a very high number I would recommend that you use a slightly custom XPath instead. XPath is essentially like ABPath but you can set a custom ending condition. I recommend that you do something like
public class TagEndingCondition : PathEndingCondition {
public int tag;
public TagEndingCondition (int tag) {
this.tag = tag;
}
public override bool TargetFound (PathNode node) {
return node.Tag == tag;
}
}
And call it like
// Start the path without the same end point as start point because we don't really have a clear end point in this case
var path = XPath.Construct(start, start, null);
// Search outwards, not towards the end point
path.heuristic = Heuristic.None;
path.endingCondition = new TagEndingCondition(2 /* (or whatever) */);
seeker.StartPath(path, OnPathComplete);
Thank you for the quick response.
I tried it like that and the path calculation works, but sadly it is just a path to the start position. I also put a Debug.Log in the new TagEndingCondition’s function “TargetFound”, and it gets never called. Any ideas, why that is happening? I will try to keep debugging it to find what’s happening there.
TargetFound is now called, but it never finds an end point and the OnPathComplete always gets a path with an error. I can’t find the problem.
The only thing that is different in my code is
return node.node.Tag == tag;
instead of your code, because the PathNode has no field for the tag.
Maybe you have any further leads? I’m out of guesses, sadly.
Hi, sorry for the late answer
That’s odd. I just tested the exact same ending condition and it is working just fine for me.
I am using this code
var start = new Vector3 (2.5f, 0, -6.5f);
var p = XPath.Construct(start, start);
p.endingCondition = new TagEndingCondition(1);
p.heuristic = Heuristic.None;
AstarPath.StartPath(p);
Are you sure you are setting the correct tag as the target and not some other tag that no node uses?
Could you show a screenshot of your graph with ‘Inspector -> Settings -> Path Debug Mode = Tags’ set?