Is there a way to force a path to go through certain nodes?

Good day everyone, I’m not sure I can word my question properly. Here’s the basic background of what’s happening.

I’m making a city-building game, I’m using a GridGraph, nodes are set 2 units apart it’s a 500 x 500 nodes graph. I’ve been working with the A* for a year now and I feel pretty comfortable with it.

So now I’m making a system that allows you to build walls for your city like in the Stronghold games. Walls can go in 8 directions (every 45 degrees). What I do is when the user drags the mouse I send a call to seeker.StartPath from where the wall should begin, to where it should end, going around houses and obstacles. The path wasn’t optimal but applying the Funnel modifier seems to make it a lot better.

What I did was making some wall pieces in blender they’re all 4 units long (2 units long would probably have made this easier but I’m trying to cut on drawcalls, so less wall pieces the better)

I have straight walls, straight-to-45, and diagonal walls.

What I’d like to do ideally is find a way to make the following statement true for every positions in path.VectorPath:
Vector3 currentPos = path.vectorPath[i];
Vector3 nextPos = path.vectorPath[i+1];

bool xDistance = Mathf.Abs(nextPos.x - currentPos.x) % 4 == 0;
bool zDistance = Mathf.Abs(nextPos.z - currentPos.z) % 4 == 0;

//What kind of modifier, or algorithm must I use to make the following true?
xDistance && zDistance;

So far what I’m doing is this:
//Will place current Node in relation to the previous one
private Vector3 ClampNodesAngles(Vector3 current, Vector3 previous){
//Get the current angle between both nodes.
Quaternion qRot = Quaternion.FromToRotation(Vector3.right, current - previous);
Vector3 eul = qRot.eulerAngles;

//Round it to the nearest 45th degree
float rot = 45 * (int)Mathf.Round(eul.y / 45);

//From previous to current, we have a straight line so we need to make sure they both sit on the same axis
if(rot % 90 == 0){
    //Path is going North/South so nodes should have the same X value
    if(rot % 180 != 0){
        return new Vector3(previous.x, current.y, current.z);  
    //Path is going East/West so nodes should have the same Z value
        return new Vector3(current.x, current.y, previous.z);  

//From previous to current we're on a diagonal line so we need to make sure that the angle between the nodes
// is exactly 45 degrees, we can make sure of that by ensuring that the xDistance and yDistance is the same
    //Assuming top = 0 degrees // East in game
    Vector3 tempVector = previous;
    //Going top left
    if(current.z > previous.z && current.x > previous.x){
    while(tempVector.z < current.z){
        tempVector.z += 4;
        tempVector.x += 4;                                     
    //Etc for all 4 diagonal directions...


But it seems like an half-assed solution and I have no idea how to do it otherwise. And of course it gives very odd results, sometimes it will get the path just fine and my wall looks awesome but more often than not there are gaps and holes.

Maybe I’m going the wrong way about this or maybe I shouldn’t be using pathfinding for this kind of things.

Thank you so much for any kind of information, feedback, pointers, death threats or any other reply to my inquiry.

That will probably never be true because of floating point arithmetic. :stuck_out_tongue:

Jokes aside.
So basically you want every node to be spaced 4 units apart.
Well, the only solution I can think of is to make a grid graph with a node size of 4, that will solve it. I guess it could be done with a grid with a node size of 2, but it would be really hacky.

If you are building walls, I would suggest merging them when they have been built into a single mesh, that will reduce drawcalls drastically. E.g using

Alright then that’s what I feared, I guess I’ll need to redo my walls so they’re 2 units long!

I can’t use 4 units for the nodes because then I lose precision for units movements.

Thank you Aron!