Need some pathfinding help

I’ve created a fairly simple A* Pathfinding script, but I have encountered one problem. The pathfinder will try and take the shortest path, only to find that there’s a one node gap between it and the target node and it keeps doubling back on itself. So it’ll move up right next to the target node, but all the nodes leading around the pathfinder are all blocked (including the one in-between the pathfinder and the target node) and the only way out is the way it came. But as soon as it moves back the way it came, it tries to re-do what it just did, and then creates this loop where it just moves back forth. I have no idea how to avoid this. What should I do?

Okay I tried a couple new things. First I created a history of the open list before it is edited. Then what I did was:

  • Check to see if the path was doubling back on itself
  • If it is, delete all the nodes on that path from the open list and clear the all lists
  • Start as if from the beginning

So what it should do is restart the path without those nodes and find another way since the path it tried to take obviously didn’t work. But what happens is once it restarts, it starts getting really wacky and creates random paths that go pretty much everywhere except the target node. I’m not sure why this is happening. Here’s the code:

    public float errorWeight = 5;
	public Vector2 pathfindingLayers;
	public List<NodeVector> nodes;
	private List<Transform> lastOpen;
	public List<Transform> open;
	public List<Transform> closed;
	public Transform start;
	public Transform current;
	public Transform finish;
	public Material yellow;
	public Material green;
	public Material red;

	void Start () {

		int a = 0;
		while(a < nodes.Count){
			int b = 0;
			while(b < nodes[a].holder.childCount){
				nodes[a].nodeVectors.Add(nodes[a].holder.FindChild((b+1).ToString()));
				b++;
			}
			a++;
		}
		current = start;
		open = FindAdjacentNodes(current);
	}

	void Update () {
	
		if(current != finish){
			CheckNode();
		}
	}

	void CheckNode () {

		float lowestF = Mathf.Infinity;
		Transform nextNode = null;
		int a = 0;
		while(a < open.Count){
			List<Transform> thisOpen = FindAdjacentNodes(open[a]);
			bool addWeight = false;
			float weight = 0;
			foreach(Transform n in thisOpen){
				if(!open.Contains(n)  !addWeight){
					addWeight = false;
					weight = 0;
				}else{
					addWeight = true;
					weight = errorWeight;
				}
			}
			if((((current.position - open[a].position).magnitude + (finish.position - open[a].position).magnitude) + weight) < lowestF){
				nextNode = open[a];
				lowestF = (current.position - open[a].position).magnitude + (finish.position - open[a].position).magnitude;
			}
			a++;
		}
		if(!closed.Contains(current)){
			closed.Add(current);
		}
		current = nextNode;
		if(!closed.Contains(current)){
			closed.Add(current);
		}
		lastOpen = open;
		open = FindAdjacentNodes(current);
		if(open.Count < 1){
			int b = 0;
			while(b < nodes.Count){
				int c = 0;
				while(c < nodes[b].nodeVectors.Count){
					foreach(Transform n in lastOpen){
						if(n == nodes[b].nodeVectors[c]){
							nodes[b].nodeVectors.Remove(nodes[b].nodeVectors[c]);
						}
					}
					c++;
				}
				b++;
			}
			closed.Clear();
			open.Clear();
			closed.Add(start);
			current = start;
			open = FindAdjacentNodes(current);
		}
		current.renderer.material = green;
	}

	List<Transform> FindAdjacentNodes (Transform node) {

		List<Transform> adjacentNodes = new List<Transform>();
		int vecColumn = 0;
		int vector = 0;
		int a = 0;
		while(a < nodes.Count){
			if(nodes[a].nodeVectors.Contains(node)){
				vecColumn = a;
				int b = 0;
				while(b < nodes[a].nodeVectors.Count){
					if(nodes[a].nodeVectors[b] == node){
						vector = b;
					}
					b++;
				}
			}
			a++;
		}

		if(vecColumn > 0){
			if(nodes[vecColumn-1].nodeVectors[vector].gameObject.layer == pathfindingLayers.x  !closed.Contains(nodes[vecColumn-1].nodeVectors[vector])){
				adjacentNodes.Add(nodes[vecColumn-1].nodeVectors[vector]); //Left
			}
			if(vector > 0  nodes[vecColumn-1].nodeVectors[vector-1].gameObject.layer == pathfindingLayers.x  !closed.Contains(nodes[vecColumn-1].nodeVectors[vector-1])){
				adjacentNodes.Add(nodes[vecColumn-1].nodeVectors[vector-1]); //Up-Left
			}
		}
		if(vector < 10){
			if(nodes[vecColumn].nodeVectors[vector+1].gameObject.layer == pathfindingLayers.x  !closed.Contains(nodes[vecColumn].nodeVectors[vector+1])){
				adjacentNodes.Add(nodes[vecColumn].nodeVectors[vector+1]); //Down
			}
			if(vecColumn < 10  nodes[vecColumn+1].nodeVectors[vector+1].gameObject.layer == pathfindingLayers.x  !closed.Contains(nodes[vecColumn+1].nodeVectors[vector+1])){
				adjacentNodes.Add(nodes[vecColumn+1].nodeVectors[vector+1]); //Down-right
			}
		}
		if(vector > 0){
			if(nodes[vecColumn].nodeVectors[vector-1].gameObject.layer == pathfindingLayers.x  !closed.Contains(nodes[vecColumn].nodeVectors[vector-1])){
				adjacentNodes.Add(nodes[vecColumn].nodeVectors[vector-1]); //Up
			}
			if(vecColumn < 10  nodes[vecColumn+1].nodeVectors[vector-1].gameObject.layer == pathfindingLayers.x  !closed.Contains(nodes[vecColumn+1].nodeVectors[vector-1])){
				adjacentNodes.Add(nodes[vecColumn+1].nodeVectors[vector-1]); //Up-Right
			}
		}
		if(vecColumn < 10  nodes[vecColumn+1].nodeVectors[vector].gameObject.layer == pathfindingLayers.x  !closed.Contains(nodes[vecColumn+1].nodeVectors[vector])){
			adjacentNodes.Add(nodes[vecColumn+1].nodeVectors[vector]); //Right
		}
		if(vecColumn > 0  vector < 10  nodes[vecColumn-1].nodeVectors[vector].gameObject.layer == pathfindingLayers.x  !closed.Contains(nodes[vecColumn-1].nodeVectors[vector])){
			adjacentNodes.Add(nodes[vecColumn-1].nodeVectors[vector+1]); //Down-left
		}

		return adjacentNodes;
	}

Help anyone? I’m sure someone has had some experience with this.

Your open list only contain the current nodes neighbors? And i am not sure how you calculate your F-value? Seems like it is only based on the distance (euclidean distance) to the end node?

Yes. Is this wrong (open node list)? And I calculate the f-values solely based off the distance from the target node. How should I do it?

The basic idea is to keep all looked up nodes in the open list and save f-values + parent, and all nodes you picked to look at neighbors from in a closed list.
If you only have neighbors in the open list then you might skip the most optimal path on more difficult routes.

F-value is normally calculated by distance to the end point as you do now AND the movement cost from the current node to the neighbor.

To get a better grasp then this is very simple explanation of the Astar: system http://www.policyalmanac.org/games/aStarTutorial.htm.

Even though it is grid based, then the ideas are more or less the same.

Alright, sounds good, I’ll try that.

Okay its working better but still doesn’t quite create the path. Here’s the new code for choosing the nodes for the path:

void CheckNode () {

		float lowestF = Mathf.Infinity;
		Transform nextNode = null;
		adjacent = FindAdjacentNodes(current);

		int a = 0;
		int openCount = open.Count;
		while(a < adjacent.Count){
			if(fCosts[openCount + a] < lowestF){
				nextNode = adjacent[a];
				lowestF = fCosts[openCount + a];
			}
			a++;
		}

		if(!closed.Contains(current)){
			closed.Add(current);
		}
		current = nextNode;
		if(!closed.Contains(current)){
			closed.Add(current);
		}
		current.renderer.material = green;
	}

And here’s the code for finding the adjacent nodes:

List<Transform> FindAdjacentNodes (Transform node) {

		List<Transform> adjacentNodes = new List<Transform>();
		int vecColumn = 0;
		int vector = 0;
		int a = 0;
		while(a < nodes.Count){
			if(nodes[a].nodeVectors.Contains(node)){
				vecColumn = a;
				int b = 0;
				while(b < nodes[a].nodeVectors.Count){
					if(nodes[a].nodeVectors[b] == node){
						vector = b;
					}
					b++;
				}
			}
			a++;
		}

		Transform left = nodes[vecColumn-1].nodeVectors[vector];
		Transform upLeft = nodes[vecColumn-1].nodeVectors[vector-1];
		Transform down = nodes[vecColumn].nodeVectors[vector+1];
		Transform downRight = nodes[vecColumn+1].nodeVectors[vector+1];
		Transform up = nodes[vecColumn].nodeVectors[vector-1];
		Transform upRight = nodes[vecColumn+1].nodeVectors[vector-1];
		Transform right = nodes[vecColumn+1].nodeVectors[vector];
		Transform downLeft = nodes[vecColumn-1].nodeVectors[vector+1];

		if(vecColumn > 0){
			if(left.gameObject.layer == pathfindingLayers.x  !closed.Contains(left)){
				adjacentNodes.Add(left); //Left
				fCosts.Add(Mathf.RoundToInt(((current.position - left.position).magnitude + (finish.position - left.position).magnitude) + 10));
			}
			if(vector > 0  upLeft.gameObject.layer == pathfindingLayers.x  !closed.Contains(upLeft)){
				adjacentNodes.Add(upLeft); //Up-Left
				fCosts.Add(Mathf.RoundToInt(((current.position - upLeft.position).magnitude + (finish.position - upLeft.position).magnitude) + 14));
			}
		}
		if(vector < 10){
			if(down.gameObject.layer == pathfindingLayers.x  !closed.Contains(down)){
				adjacentNodes.Add(down); //Down
				fCosts.Add(Mathf.RoundToInt(((current.position - down.position).magnitude + (finish.position - down.position).magnitude) + 10));
			}
			if(vecColumn < 10  downRight.gameObject.layer == pathfindingLayers.x  !closed.Contains(downRight)){
				adjacentNodes.Add(downRight); //Down-right
				fCosts.Add(Mathf.RoundToInt(((current.position - downRight.position).magnitude + (finish.position - downRight.position).magnitude) + 14));
			}
		}
		if(vector > 0){
			if(up.gameObject.layer == pathfindingLayers.x  !closed.Contains(up)){
				adjacentNodes.Add(up); //Up
				fCosts.Add(Mathf.RoundToInt(((current.position - up.position).magnitude + (finish.position - up.position).magnitude) + 10));
			}
			if(vecColumn < 10  upRight.gameObject.layer == pathfindingLayers.x  !closed.Contains(upRight)){
				adjacentNodes.Add(upRight); //Up-Right
				fCosts.Add(Mathf.RoundToInt(((current.position - upRight.position).magnitude + (finish.position - upRight.position).magnitude) + 14));
			}
		}
		if(vecColumn < 10  right.gameObject.layer == pathfindingLayers.x  !closed.Contains(right)){
			adjacentNodes.Add(right); //Right
			fCosts.Add(Mathf.RoundToInt(((current.position - right.position).magnitude + (finish.position - right.position).magnitude) + 10));
		}
		if(vecColumn > 0  vector < 10  downLeft.gameObject.layer == pathfindingLayers.x  !closed.Contains(downLeft)){
			adjacentNodes.Add(downLeft); //Down-left
			fCosts.Add(Mathf.RoundToInt(((current.position - downLeft.position).magnitude + (finish.position - downLeft.position).magnitude) + 14));
		}

		return adjacentNodes;
	}

And here’s a picture of the path its generating:

Orange = Start point
Blue = Walkable nodes
Yellow = Un-walkable nodes
Brown = Target node
Green = Generated path

No need for this double check

 if(!closed.Contains(current)){

            closed.Add(current);

        }

        current = nextNode;

        if(!closed.Contains(current)){

            closed.Add(current);

        }

Having a hard time understanding your code, maybe this will help. It is one of my old systems (not grid based but waypoint based). It is awfully implemented and slow, but rather short and might give you an idea of how to do it:

  public List<Vector3> path       = new List<Vector3>();
  public GameObject[] waypoints   = new GameObject[1];
  public List<Node> openlist      = new List<Node>();
  public List<Node> closedlist    = new List<Node>();
  public Transform endPos;
  private Node sN                 = new Node();
  private Node eN                 = new Node();
  private Node parent             = new Node(0, Vector3.zero);
  
  void Start () 
  {
    FindWaypointNeighbours();
  }

  void Update() 
  {
    if (Input.GetKeyUp(KeyCode.P))
      FindPath();
   }

  private void FindPath()
  {
    if(openlist != null)
      openlist.Clear();
    if(closedlist != null)
      closedlist.Clear();
    if(path != null)
      path.Clear();

    sN = FindNode(transform.position);
    eN = FindNode(endPos.position);
    int p   = sN.index;
    parent = new Node(sN);
 
    closedlist.Add(sN);
    int t = 0;

    //while searching for the index of the end node
    while (p != eN.index)
    {
      foreach (int i in parent.n)
      {
          if (i == eN.index)
          {
            p = eN.index;
            break;
          }
          if (!IsItOnClosedList(i))
            if (!IsItOnOpenList(i))
            {
              AddNode(i, parent);
            }
      }

      //we found the end node so backtrack it parents into path and then break out!
      if (p == eN.index)
      {
        eN.p = new Node(parent);
        int k = -1;
        Node l = new Node(eN);
        path.Add(eN.pos);

        while (k != sN.index)
        {
          k = l.p.index;
          l = new Node(l.p);
          path.Add(l.pos);
        }
        break;
      }

      //we didnt found parent yet find node with lowest score
      parent  = new Node(ReturnLowestNode());
      p       = parent.index;
      
      closedlist.Add(parent);
      RemoveFromOpen(p);
      t++;
    }
  }

  private void RemoveFromOpen(int i)
  {
    for (int j = 0; j < openlist.Count; j++)
      if (openlist[j].index == i)
      {
        openlist.RemoveAt(j);
        break;
      }

  }

  private Node ReturnLowestNode()
  {
    float cF  = 1000.0f;
    int index     = 0;
    
    for(int i = 0; i < openlist.Count; i++)
      if (openlist[i].f < cF)
      {
        index   = i;
        cF      = openlist[i].f;
      }
    return openlist[index];
  }

  private void AddNode(int i, Node par)
  {
    Node n  = new Node(i, waypoints[i].transform.position, waypoints[i].GetComponent<WayPoints>().nI);
    n.p     = par;
    n.g     = par.g + Vector3.Distance(par.pos, n.pos);
    n.h     = Vector3.Distance(waypoints[i].transform.position, endPos.position);
    n.f = n.g + n.h;
    openlist.Add(n);
  }

  private bool IsItOnClosedList(int i)
  {
    foreach (Node n in closedlist)
      if (n.index == i)
        return true;

    return false;
  }

  private bool IsItOnOpenList(int i)
  {
    foreach (Node n in openlist)
      if (n.index == i)
        return true;

    return false;
  }

  private Node FindNode(Vector3 v)
  {
    float dist = 1000.0f;
    int j      = 0;

    for(int i = 0; i < waypoints.Length; i++)
        if (Vector3.Distance(v, waypoints[i].transform.position) < dist)
        {
          dist    = Vector3.Distance(v, waypoints[i].transform.position);
          j       = i;
        }
    Node n = new Node(waypoints[j].GetComponent<WayPoints>().index, waypoints[j].transform.position, waypoints[j].GetComponent<WayPoints>().nI);
    return n;
  }

  private void FindWaypointNeighbours()
  {
    for(int i = 0; i <  waypoints.Length; i++)
      for (int j = 0; j < waypoints.Length; j++)
        if (i != j)
        {
          RaycastHit hit;
          Vector3 dir = (waypoints[j].transform.position - waypoints[i].transform.position).normalized;
          if (Physics.Raycast(waypoints[i].transform.position, dir, out hit, 100.0f))
          {
            if (hit.transform == waypoints[j].transform)
              waypoints[i].GetComponent<WayPoints>().nI.Add(j);
          }
        }
     
  }

And the Node code:

public class Node
{
  public int index       = 0;
  public float g         = 0f;
  public float h         = 0f;
  public float f         = 0f;
  public Node p;
  public Vector3 pos     = Vector3.zero;
  public List<int> n;

  public Node()
  {
    Debug.Log("New empty node");
  }

  public Node(int i, Vector3 p)
  {
    index = i;
    pos = p;
  }

  public Node(int i, Vector3 p, List<int> l)
  {
    index   = i;
    pos     = p;
    n       = l;
  }

  public Node(Node k)
  {
    index   = k.index;
    g       = k.g;
    h       = k.h;
    f       = k.f;
    p       = k.p;
    pos     = k.pos;
    n       = k.n;
  }	
}

Having a hard time understanding your code too. I’ll go through my code piece by piece here in a second.

public class NodeVector {

	public string name = "Column ";

	public Transform holder;
	public List<Transform> nodeVectors;
}

…a column of nodes (Transform holder being the parent of all the nodes in the column and nodeVectors being the nodes in the columns.

public Vector2 pathfindingLayers;

…a variable holding the layer numbers for the pathfinding layers “walkable” and “unwalkable”, “walkable” being x and “unworkable” being y.

public List<NodeVector> nodes;

…variable containing all the nodes.

private List<Transform> lastOpen;
public List<Transform> open;
public List<int> fCosts;
public List<Transform> closed;
public List<Transform> adjacent;

lastOpen is the history of all the nodes on the open list before the last change was made. open is the open list, fCosts is the list of f-costs for each node, closed is the closed list, and adjacent is a list containing the adjacent nodes of the current node.

public Transform start;
public Transform current;
public Transform finish;

…the starting node, the current node, and the end node.

void Start () {

	int a = 0;
	while(a < nodes.Count){
		int b = 0;
		while(b < nodes[a].holder.childCount){
			nodes[a].nodeVectors.Add(nodes[a].holder.FindChild((b+1).ToString()));
			b++;
		}
		a++;
	}

	current = start;
	open = FindAdjacentNodes(current);
}

…assign the columns of nodes, make the current node the starting node, and add all the adjacent nodes of the current node to the open list.

void Update () {
	
	if(current != finish){
		CheckNode();
	}
}

…if the current node isn’t the target node, continue pathfinding.

void CheckNode () {

…initialize the CheckNode function.

float lowestF = Mathf.Infinity;
Transform nextNode = null;
adjacent = FindAdjacentNodes(current);

…set the search variables, making the lowest f value infinity, creating a next node variable, and setting the adjacent list.

int a = 0;
int openCount = open.Count;
while(a < adjacent.Count){
	if(fCosts[openCount + a] < lowestF){
		nextNode = adjacent[a];
		lowestF = fCosts[openCount + a];
	}
	a++;
}

…run a while loop through all the adjacent nodes. Check to see if the node’s f-cost is less than the lowest f-cost. If it is, make nextNode the adjacent node, and make lowestF the f-cost of the node. This will find the node with the lowest f-cost.

current = nextNode;
if(!closed.Contains(current)){
	closed.Add(current);
}

…make the current node nextNode and add it to the closed list if it isn’t currently in it.

List<Transform> FindAdjacentNodes (Transform node) {

…initialize the FindAdjacentNodes function which returns a list of nodes adjacent to Transform node.

List<Transform> adjacentNodes = new List<Transform>();
int vecColumn = 0;
int vector = 0;

…create a list to hold the adjacent nodes, and set the variables for finding adjacent nodes. vecColumns is an int showing which column the current node is in, and vector is an int showing which row the node is in.

int a = 0;

while(a < nodes.Count){
	if(nodes[a].nodeVectors.Contains(node)){
		vecColumn = a;
		int b = 0;
		while(b < nodes[a].nodeVectors.Count){
			if(nodes[a].nodeVectors[b] == node){
				vector = b;
			}
			b++;
		}
	}
	a++;
}

…find which column and row the current node is in.

Transform left = nodes[vecColumn-1].nodeVectors[vector];
Transform upLeft = nodes[vecColumn-1].nodeVectors[vector-1];
Transform down = nodes[vecColumn].nodeVectors[vector+1];
Transform downRight = nodes[vecColumn+1].nodeVectors[vector+1];
Transform up = nodes[vecColumn].nodeVectors[vector-1];
Transform upRight = nodes[vecColumn+1].nodeVectors[vector-1];
Transform right = nodes[vecColumn+1].nodeVectors[vector];
Transform downLeft = nodes[vecColumn-1].nodeVectors[vector+1];

…set the variables for all 8 possible adjacent nodes.

Then after that is the intricate code for checking to see if the 8 nodes are actually there, whether or not they’re walkable, if they’re on the closed list, if they’re on the open list, and calculation of the f-cost:

if(vecColumn > 0){
			Transform left = nodes[vecColumn-1].nodeVectors[vector];
			if(left.gameObject.layer == pathfindingLayers.x  !closed.Contains(left)){
				//if(!open.Contains(left)){
					adjacentNodes.Add(left); //Left
					left.parent = current;
					fCosts.Add(Mathf.RoundToInt(((current.position - left.position).magnitude + (finish.position - left.position).magnitude) + 10));
				//}
			}
			Transform upLeft = nodes[vecColumn-1].nodeVectors[vector-1];
			if(vector > 0  upLeft.gameObject.layer == pathfindingLayers.x  !closed.Contains(upLeft)){
				//if(!open.Contains(upLeft)){
					adjacentNodes.Add(upLeft); //Up-Left
					upLeft.parent = current;
					fCosts.Add(Mathf.RoundToInt(((current.position - upLeft.position).magnitude + (finish.position - upLeft.position).magnitude) + 14));
				//}
			}
		}
		if(vector < 10){
			Transform down = nodes[vecColumn].nodeVectors[vector+1];
			if(down.gameObject.layer == pathfindingLayers.x  !closed.Contains(down)){
				//if(!open.Contains(down)){
					adjacentNodes.Add(down); //Down
					down.parent = current;
					fCosts.Add(Mathf.RoundToInt(((current.position - down.position).magnitude + (finish.position - down.position).magnitude) + 10));
				//}
			}
			Transform downRight = nodes[vecColumn+1].nodeVectors[vector+1];
			if(vecColumn < 10  downRight.gameObject.layer == pathfindingLayers.x  !closed.Contains(downRight)){
				//if(!open.Contains(downRight)){
					adjacentNodes.Add(downRight); //Down-right
					downRight.parent = current;
					fCosts.Add(Mathf.RoundToInt(((current.position - downRight.position).magnitude + (finish.position - downRight.position).magnitude) + 14));
				//}
			}
		}
		if(vector > 0){
			Transform up = nodes[vecColumn].nodeVectors[vector-1];
			if(up.gameObject.layer == pathfindingLayers.x  !closed.Contains(up)){
				//if(!open.Contains(up)){
					adjacentNodes.Add(up); //Up
					up.parent = current;
					fCosts.Add(Mathf.RoundToInt(((current.position - up.position).magnitude + (finish.position - up.position).magnitude) + 10));
				//}
			}
			Transform upRight = nodes[vecColumn+1].nodeVectors[vector-1];
			if(vecColumn < 10  upRight.gameObject.layer == pathfindingLayers.x  !closed.Contains(upRight)){
				//if(!open.Contains(upRight)){
					adjacentNodes.Add(upRight); //Up-Right
					upRight.parent = current;
					fCosts.Add(Mathf.RoundToInt(((current.position - upRight.position).magnitude + (finish.position - upRight.position).magnitude) + 14));
				//}
			}
		}
		Transform right = nodes[vecColumn+1].nodeVectors[vector];
		if(vecColumn < 10  right.gameObject.layer == pathfindingLayers.x  !closed.Contains(right)){
			//if(!open.Contains(right)){
				adjacentNodes.Add(right); //Right
				right.parent = current;
				fCosts.Add(Mathf.RoundToInt(((current.position - right.position).magnitude + (finish.position - right.position).magnitude) + 10));
			//}
		}
		Transform downLeft = nodes[vecColumn-1].nodeVectors[vector+1];
		if(vecColumn > 0  vector < 10  downLeft.gameObject.layer == pathfindingLayers.x  !closed.Contains(downLeft)){
			//if(!open.Contains(downLeft)){
				adjacentNodes.Add(downLeft); //Down-left
				downLeft.parent = current;
				fCosts.Add(Mathf.RoundToInt(((current.position - downLeft.position).magnitude + (finish.position - downLeft.position).magnitude) + 14));
			//}
		}

It checks to see if the node is there depending on the values of vecColumn/vector and then assigns the variable, checks the layer of the node, then checks to see if its on the closed list. If so, it adds it to adjacentNodes, parents the nodes, then calculates its f-cost.

	return adjacentNodes;
}

…return the adjacent nodes.

So thats an explanation of the code I’ve written.

Made a bit more sense now.

  1. You are still only holding neighbor’s in the open list. There should only be one open list holding every node that is ever looked at, and not picked and put on the closed list yet. (If they are picked as current and put on the closed list, the remember to remove it from the open list)
open = FindAdjacentNodes(current);
  1. When you add your nodes from the “map” onto the open list and change them you also change them on the actual map which can give problems next time you look it up.
Transform left = nodes[vecColumn-1].nodeVectors[vector];

if(left.gameObject.layer == pathfindingLayers.x  !closed.Contains(left))
{
   adjacentNodes.Add(left); 

   left.parent = current;

   fCosts.Add(Mathf.RoundToInt(((current.position - left.position).magnitude + (finish.position - left.position).magnitude) + 10));
}

See what i do here in my example: i create a NEW! instance which is then put into my open list such that i does not change my actual map:

private void AddNode(int i, Node par)

  {
     //Here i create a new just like the one i want to put on the open list
    Node n  = new Node(i, waypoints[i].transform.position, waypoints[i].GetComponent<WayPoints>().nI);

    n.p     = par;

    n.g     = par.g + Vector3.Distance(par.pos, n.pos);

    n.h     = Vector3.Distance(waypoints[i].transform.position, endPos.position);

    n.f = n.g + n.h;

    openlist.Add(n);

  }

Oops, sorry I didn’t include the code that held all the nodes in the open list. The last thing it does in the CheckNode() function is add all the possible adjacent nodes to the open list:

 open.AddRange(FindAdjacentNodes(current));

But now, the path gets even weirder:

Try not adding nodes from the node map, but create new instances of them and out on the open list.

Can’t seem to find how to create an instance of a Transform (new Transform() ) doesn’t work.

It didn’t make a difference. I created the new instances of the Transform’s by instantiating it so that might be part of the problem.

Yes might might be a problem. Because if you change the actual map nodes then the second path you need to fidn will likely be a mess.

However for your initial problem i see a few more mistakes. You need to check if a node is already on the open list. You out commented that part, but else you add the same node mutiple times and keeps changing the parents. What you can do to begin with is to change its parent if it is on the open list, to the current. In reality you need to check if the path is faster from the new parent when you move diagonal, but wait with that. And maybe start by only checking for neighbors up, down, left, right to remove this problem.

Furthermore you never seem to remove a node from the open list. When you find the new current node and put it in closed list you need to remove it from the open list as well as your fvalue list.

Sorry for all my mistakes in the post, is writing from an ipad.

Alright, I did all of that and it still was giving me a pretty weird path.