In a grid constrained movement, how to move to the closest walkable tile close to an obstacle?


TL;DR - How to get the nearest walkable node to a clicked point? Any API method for it?
I.e. clicked in an obstacle, then gett the closest walkable point.

Long version:
My question title may be confusing, so I’ll detail: I have a tile constrained movement and if I click in a tile the character will move to that tile.

But if I click in an obstacle I should move to the closest walkable tile. At the moment the Grid Graph is returning a waypoint that is half of the obstacle. But why is that hapenning? Shouldn’t be default behavior to not return a waypoint in an obstacle?

In my next screenshots:

  • Green = obstacle
  • Black = character
  • Selection box = clicked tile

So when clicking the obstacle tile, what should happen is moving to a tile at the side of it, like this:

What is actually hapenning, Grid Graph is returning a waypoint that is in half the obstacle tile:

In the code I’m simply getting the waypoints:
actualWaypoint = path.vectorPath[currentWaypoint];

What I’m trying to accomplish is similar to RimWorld. In this screenshot I clicked in the rocks and the target has been set to the closest free tile:

This is the grid:

Clicking the obstacle:

Clicking a walkable tile:

And clicking in the middle of a block of obstacles makes the character land in the middle of the lower border:

I tried:
`// destination = click position
NNInfo info =, NNConstraint.Default);

		Instantiate(PositionMarker, info.clampedPosition, Quaternion.identity);
		seeker.StartPath (transform.position,info.clampedPosition, OnPathComplete);

But this also returned a point in the middle of an obstacle…

Any help will be appreciated, thanks.


Grid graphs treat nodes as having a size, so the closest point on them will be on the edge of the square that makes up the node.

If you want to get the closest node center, use
(Vector3)info.node.position instead of info.clampedPosition

You can also set the seeker->Start End Modifier -> End Point to SnapToNode instead of ClosestOnNode which will give you the behaviour you want without any extra code.

Awesome, Aron! Thanks for the very fast answer.