I’ve gone through the video twice and I’ve tried tracing the issue back to GetNeibourList but it looks correct. I’m pretty stuck. This is the error:
There must be another place that has a typo or my gridPos checks are incorrect. I just dont see it.
My Pathfinding.cs code:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Pathfinding : MonoBehaviour
{
public static Pathfinding Instance { get; private set; }
private const int MOVE_STRAIGHT_COST = 10;
private const int MOVE_DIAGONAL_COST = 14;
[SerializeField] private Transform gridDebugObjectPrefab;
private int width;
private int height;
private float cellSize;
private GridSystem<PathNode> gridSystem;
private void Awake() {
if(Instance !=null)
{
Debug.LogError(" There's more than one Pathfinding " + transform + " - " + Instance);
Destroy(gameObject);
return;
}
Instance = this;
gridSystem = new GridSystem<PathNode>(10, 10, 2f,
(GridSystem<PathNode> g, GridPos gridPos) => new PathNode(gridPos));
gridSystem.CreateDebugObjects(gridDebugObjectPrefab);
}
public List<GridPos> FindPath(GridPos startGridPos, GridPos endGridPos)
{
List<PathNode> openList = new List<PathNode>();
List<PathNode> closedList = new List<PathNode>();
PathNode startNode = gridSystem.GetGridObject(startGridPos);
PathNode endNode = gridSystem.GetGridObject(endGridPos);
openList.Add(startNode);
for (int x = 0; x < gridSystem.GetWidth(); x++)
{
for (int z = 0; z < gridSystem.GetHeight(); z++)
{
GridPos gridPos = new GridPos(x, z);
PathNode pathNode = gridSystem.GetGridObject(gridPos);
pathNode.SetGCost(int.MaxValue);
pathNode.SetHCost(0);
pathNode.CalculateFCost();
pathNode.ResetCameFromPathNode();
}
}
startNode.SetGCost(0);
startNode.SetHCost(CalculateDistance(startGridPos, endGridPos));
startNode.CalculateFCost();
while (openList.Count > 0)
{
PathNode currentNode = GetLowestFCostPathNode(openList);
if(currentNode == endNode)
{
return CalculatePath(endNode);
}
openList.Remove(currentNode);
closedList.Add(currentNode);
foreach (PathNode neighbourNode in GetNeibourList(currentNode))
{
if(closedList.Contains(neighbourNode))
{
continue;
}
int tentativeGCost =
currentNode.GetGCost() + CalculateDistance(currentNode.GetGridPos(), neighbourNode.GetGridPos());
if(tentativeGCost < neighbourNode.GetGCost())
{
neighbourNode.SetCameFromPathNode(currentNode);
neighbourNode.SetGCost(tentativeGCost);
neighbourNode.SetHCost(CalculateDistance(neighbourNode.GetGridPos(), endGridPos));
neighbourNode.CalculateFCost();
if(!openList.Contains(neighbourNode))
{
openList.Add(neighbourNode);
}
}
}
}
//No Path Found
return null;
}
public int CalculateDistance(GridPos gridPosA, GridPos gridPosB)
{
GridPos gridPosDistance = gridPosA - gridPosB;
int xDistance = Mathf.Abs(gridPosDistance.x);
int zDistance = Mathf.Abs(gridPosDistance.z);
int remaining = Mathf.Abs(xDistance - zDistance);
return MOVE_DIAGONAL_COST * Mathf.Min(xDistance, zDistance) + MOVE_STRAIGHT_COST * remaining;
}
private PathNode GetLowestFCostPathNode(List<PathNode> pathNodeList)
{
PathNode lowestFCostPathNode = pathNodeList[0];
for (int i = 0; i < pathNodeList.Count; i++)
{
if (pathNodeList[i].GetFCost() < lowestFCostPathNode.GetFCost())
{
lowestFCostPathNode = pathNodeList[i];
}
}
return lowestFCostPathNode;
}
private PathNode GetNode(int x, int z)
{
Debug.Log($"Getting node at {x},{z} Gridsize: Width " + gridSystem.GetWidth() + " Height " + gridSystem.GetHeight());
return gridSystem.GetGridObject(new GridPos(x, z));
}
private List<PathNode> GetNeibourList(PathNode currentNode)
{
List<PathNode> neighbourList = new List<PathNode>();
GridPos gridPos = currentNode.GetGridPos();
if (gridPos.x - 1 >= 0)
{
//left
neighbourList.Add(GetNode(gridPos.x - 1, gridPos.z + 0));
if (gridPos.z -1 >= 0)
{
//left down
neighbourList.Add(GetNode(gridPos.x - 1, gridPos.z - 1));
}
if(gridPos.z + 1 < gridSystem.GetHeight())
{
//left up
neighbourList.Add(GetNode(gridPos.x - 1, gridPos.z + 1));
}
}
if(gridPos.x + 1 < gridSystem.GetWidth())
{
//right
neighbourList.Add(GetNode(gridPos.x + 1, gridPos.z + 0));
if (gridPos.z - 1 >= 0)
{
//right down
neighbourList.Add(GetNode(gridPos.x + 1, gridPos.z - 1));
}
if(gridPos.z + 1 < gridSystem.GetHeight())
{
//right up
neighbourList.Add(GetNode(gridPos.x + 1, gridPos.z + 1));
}
}
if (gridPos.z - 1 >= 0)
{
//down
neighbourList.Add(GetNode(gridPos.x + 0, gridPos.z - 1));
}
if(gridPos.z + 1 < gridSystem.GetHeight())
{
//up
neighbourList.Add(GetNode(gridPos.x + 0, gridPos.z + 1));
}
return neighbourList;
}
private List<GridPos> CalculatePath(PathNode endNode)
{
List<PathNode> pathNodeList = new List<PathNode>();
pathNodeList.Add(endNode);
PathNode currentNode = endNode;
while (currentNode.GetCameFromPathNode() != null)
{
pathNodeList.Add(currentNode.GetCameFromPathNode());
currentNode = currentNode.GetCameFromPathNode();
}
pathNodeList.Reverse();
List<GridPos> gridPosList = new List<GridPos>();
foreach(PathNode pathNode in pathNodeList)
{
gridPosList.Add(pathNode.GetGridPos());
}
return gridPosList;
}
}
Any help appreciated