- A* version: 5.3.1
- Unity version: 2022.3.48f1
I’m running into an issue with penalties. I’m using a grid graph with an initial penalty of 1000.
When I place a road, I’m running this
var node = AstarPath.active.GetNearest(this.transform.position).node;
node.Penalty = (uint)500;
Then subsequently I run
var bounds = entity.GetCollider().bounds;
AstarPath.active.UpdateGraphs(bounds);
which just updates the graphs using the roads collider bounds, which should be one. I’ve also tried manually running scan by pressing the actual ‘scan’ button on the inspector. The problem is, all the node’s penalties everywhere are 1000 even though when I step through, I see them being set to 500.
What am I missing?
Any ideas? (Not trying to be annoying but I’m stumped)
As in, it sets them to 500, then sets them back to 1000? Is there a trigger for them being set back to 1000, such as “when X happens” or is immediately, and for all of them?
Not annoying at all Sorry for the delay, I know the frustration
So when this code runs
var node = AstarPath.active.GetNearest(this.transform.position).node;
node.Penalty = (uint)500;
I step over it and I see that the node’s penalty was changed from 1000 to 500.
But when I look at the debug graph view showing me the penalty for all the nodes, they’re all at 1000.
Also thanks for replying
1 Like
So, looking at your use case here, is there any specific reason you’re wanting to change the penalty by bounds rather than using tags? I need to do some research on setting penalties but while looking up stuff I had that thought.
I suppose I could use tags. I didn’t take the time to understand them and thought this approach was easier but maybe using tags is the better option
Sounds like it yeah I’d say give it a try and let us know how it goes
Ok I’ve finally gotten back around to this issue. And I’ve started using tags. The issue I’m running into is that I can see the tags applied but they’re removed when I call this:
var bounds = entity.GetCollider().bounds;
AstarPath.active.UpdateGraphs(bounds);
I noticed this is overloaded with a GraphUpdateObject parameter. I’m not sure what is the best way forward. My intention was to remove nodes from the graph when a building is placed down but this doesn’t seem plausible.
Is the implementation of using tags and removing nodes from the graph hard to accomplish? Should I just be leaving all nodes in the graph but mark some of them as unwalkable when a building is placed?
Yeah really not sure what the thought process is behind all of these function calls.
I’m trying to create a graph then when placing ‘land tiles’ set those land tiles of type tag = land.
But when I scan AstarPath.active.Scan() again, all this data is lost. This seems incredibly unintuitive and is causing me a lot of frustration.
Looking into graph updates, I’m noticing this line in the documentation on the graph updates page:
Graph data must only be modified when it is safe to do so. Pathfinding might be running at any time so it is necessary to first pause the pathfinding threads and then update the data. The easiest way to do this is to use AstarPath.AddWorkItem
My understanding (and this is a weak area of knowledge for me, my apologies) is that you can’t directly slap new data on top of the graph, you need to do it in a work item if it’s during gameplay. Take a look at these code examples:
AstarPath.active.AddWorkItem(new AstarWorkItem(() => {
// Safe to update graphs here
var node = AstarPath.active.GetNearest(transform.position).node;
node.Walkable = false;
}));
AstarPath.active.AddWorkItem(() => {
// Safe to update graphs here
var node = AstarPath.active.GetNearest(transform.position).node;
node.position = (Int3)transform.position;
});
The Using direct access to graph data section of that page has a lot of useful information on this specific subject. Also the section under that one, " Viewing the results of updates" may also be useful for troubleshooting/learning this.
If you’re still having issues with this let me know and I’ll figure this out Any code or settings you’re using will also help
Hi
Instead of manipulating penalties and walkability manually, I would suggest a more robust solution:
Try to use the Per Layer Modifications grid graph rule:
The workflow would be this:
- Make sure the road tile is on a separate layer, for example “Roads”
- Configure the Per Layer Modifications grid graph rule to make all nodes on top of objects with the “Roads” layer to be assigned a specific tag.
- Place down your road tile
- Update the graph around that tile using
UpdateGraphs(bounds)
Whenever the road tile is removed, you can also run UpdateGraphs(bounds)
, and it will automatically remove the tag.
This will be much less finicky compared to manually changing the graph.
1 Like