Support Forum

Agent ignores penalty by going diagonally

Using a grid graph, and as shown in a picture, an agent completely ignores penalty by cutting the nodes diagonally:

The blue nodes are marked as walkable.
The blue nodes have tag “Wall”, which has a penalty cost of 500,000 in a Seeker for the agent:

When I remove any diagonal node possibility for the agent, the path is calculated correctly:

When I make the nodes not traversable in Tags, the path is calculated correctly

However the tag needs to be traversable so enemies can path through walls if path is too long to get to the player and attack him.

I have tried removing all modifiers from the agent, as well as using funnel, simple smooth or raycast, still the same issue.

Grid Setup:

How to solve this issue? Am I doing something wrong, or could this be a bug?

Thank you!

I am also recalculating all connections using
graph.GetNodes(node => graph.CalculateConnections((GridNodeBase)node));


Sorry for the late reply, I’ve been sick these last few weeks.

That is expected behavior, the agent never moves over the nodes that have a penalty if it moves diagonally like that.

Hello @aron_granberg,

not sure I understand your answer, even though I must have read it more than 5 times :slight_smile:
What do you mean by “agent never moves over the nodes that have a penalty if it moves diagonally like that.”?

The agent does move over nodes with penalties diagonally, but it should not, correct? It should behave like in any other scenario it is not suppose to move over the nodes (e.g. they are not traversable).

How to make so the agent cannot move diagonally as shown in the picture?

Unwanted behaviour
Expected behaviour:

when using only penalties on blue nodes in the picture

So if I understand correctly, the grid graph is just unusable when using penalties? Since if agents cross diagonally, it defeats the entire purpose of grid tiles.


I’ve been thinking about this.
So the main issue is that by going diagonally, the agent never actually moves over the nodes you have added penalties to. Currently, there’s no out of the box way to change this behavior.

However, I did come up with a solution, but it requires a minor change to the code.
If you open the GridNode.cs script, there should be a comment saying:

// Check if the other node has not yet been visited by this path

Right before that comment, add this snippet of code:

if (dir >= 4) {
        // Get the two axis aligned neighbours that we are moving between
	var d1 = dir - 4;
	var d2 = (dir - 4 + 1) % 4;
	var n1 = this.GetNeighbourAlongDirection(d1);
	var n2 = this.GetNeighbourAlongDirection(d2);
	// Theroretically reasonable scaling factor.
	// This will make moving diagonally across a grid of nodes with penalties
	// equally costly per unit of distance as moving in an axis aligned direction.
	const float SQRT2_MINUS_1 = 0.414213f;
	if (n1 != null) tmpCost += (uint)(path.GetTraversalCost(n1) * (SQRT2_MINUS_1 * 0.5f));
	if (n2 != null) tmpCost += (uint)(path.GetTraversalCost(n2) * (SQRT2_MINUS_1 * 0.5f));

Thank you @aron_granberg very much! I cannot test this, as we are using the beta of the pathfinding and have your asset only as a manifest package, thus the code cannot be edited. Not sure how hard it is, but would you be able to deploy this addition to the beta? Maybe adding some optional flag into the grid graph?

Such a functionality seems like a common usage for many devs using grids.


What you can do is just copy and paste the package into your project for testing. Take a look at this page: Unity - Manual: Embedded dependencies under the Copying a Unity package from the cache section. Move it to Assets/AstarPathfindingProject.

Let me know how it works for you and maybe I’ll include it in the main package. :slight_smile:

@aron_granberg big thanks for all your help! The provided solution works like a charm.

Would it be possible now to add it into an official beta release? Maybe like an option somwehere? Since the code is changed just manually, updating the package any time in the future would always just rewrite this fix.

1 Like

Helo @aron_granberg, not sure if you remember this issue, but the fix code provided by you no longer works with the newest BETA version.
Is there any way how to fix this issue again? Or has it been maybe implemented as some flag?


Why does it no longer work?

My mistake, I did use a different modifier and it didnt work with that. But works with simple smooth.

1 Like