How to use tags to get a custom nearest node?


Is there a way to get a nearest node that considers a hidden connection?

Here is what I have…

As shown in the image, the soldier needs to get to point “A”, so the Pathfinding calculates “C” as the nearest node, which is correct.

But how can I configurate Astar so the Pathfinding returns “B” as the nearest node?

My approach is to assign a different tag to the destroyable blocks, so the Pathfinding consider them in the proximity calculation (but without allowing the soldier to walk by them).

I’m tagging the destroyable blocks using this custom GraphUpdateObject…

public class DestroyableGUO : GraphUpdateObject { public override void Apply(Node node) { // Set tag "Destroyable" node.tags = 3; } }

And every time I update the graph I execute…

`foreach (GameObject destructibleEntity in destructibleEntities)
GraphUpdateObject guo = new DestroyableGUO();
guo.bounds = destructibleEntity.transform.GetChild(0).collider.bounds;;

Where destructibleEntities is an ArrayList of the destroyable blocks.

To this part, everything is working.

Then, to find the nearest node I use this custom NNConstraint

NNConstraint nn = NNConstraint.Default; nn.constrainArea = true; nn.area = nearestToSoldier.area; // Soldier's node area nn.constrainTags = true; nn.tags = (1 << 1 | 1 << 3 | 1 << 4); // 1: "Ground", 3: "Destroyable", 4: "Collectable"

But It doesn’t work :frowning:

Am I going in the right direction?, Is there a way to do what I need?, or do I have to think in a workaround?

Thank you for your time!

What I would do is to mark that door and destroyable with a specific tag, but not making them unwalkable. Then I would request a path as normal, but when I got the path back, I would loop through the nodes and check if it would traverse any destroyable block node. If that happened, well, that depends on the game. Probably move just up until that point and then destroy the block or something.

With this you could also add a penalty to the destroyable blocks to avoid NPCs (or the player or whatever) to destroy blocks without needing to (e.g when they could just have walked one block to the right or something).

That is what I did.

I set those blocks as “walkable”, so the soldier finds the path that lies on them, and walks it until he hits the block :wink:

This works for now, because I know a priori what objects are blocking a path. But in a near future the maps are going to be dynamically generated.

My previous approach (second) was to set all objects as “walkable” and assign them a tag with a high penalty (Seeker’s tag penalty configuration), so the soldier finds a path over them only as last option.

To do this I used the same custom GraphUpdateObject shown above, but only the tag was assigned, and the penalty was always “1” for everything. I also tried setting the penalty in the custom GraphUpdateObject.

public class DestroyableGUO : GraphUpdateObject { public override void Apply(Node node) { // Set tag "Destroyable" node.tags = 3; node.penalty = 50; } }

But it didn’t work as I expected. Maybe something was misconfigured.

Anyway, thank you!

Greetings :wink:

Not exactly sure how it did not work as expected, but if it was that you didn’t notice any penalties, that could have been because the penalty was set too low. Try setting it to values like 1000 or 10000, usually very large values are required.
Also, if the graph update object has updatePhysics set to true, it will first reset the penalties before applying the new ones. This could interfer if you are using many graph update objects to apply penalties (the dev version has a toggle to disable this).

It works! thank you!!!

It works independently of the guo.updatePhysics value. I tried both cases.

I’m going to set it to false just in case. I don’t know what it really does.

Thank you again!