ArgumentOutOFRangeException

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 :slight_smile:

That is a bit of a stumper, as the debugs would seem to indicate that you’re getting the out of range error on 0,1, which should be just fine.

Let’s add an additional debug, this one in GridSystem.cs
Please note that this will not prevent the error we currently have things structured, but may lend some insight: Modify your GetGridObject method like this:

    public TGridObject GetGridObject(GridPosition gridPosition)
    {
        if (!IsValidGridPosition(gridPosition))
        {
            Debug.LogError($"GridSystem:  Trying to retrieve GridObject from {gridPosition}, which is out of range.");
        }
        return gridObjectArray[gridPosition.x, gridPosition.z];
    }
1 Like

The problem is definitely not in PathFinding. I pasted this in my project and got no error.

Thank you both for taking a look at this!

So, I went back to my testing.cs and found that I had forgot the -1 in the for loop when pressing T. I suppose my clue was when I was writting my original response that the testing.cs/testing object always seemed a bit buggy…

Anyway,

if(Input.GetKeyDown(KeyCode.T))
		{
			GridPos mouseGridPos = LevelGrid.Instance.GetGridPos(MouseWorld.GetPos());
			GridPos startGridPos = new GridPos(0, 0);

			List<GridPos> gridPosList =  Pathfinding.Instance.FindPath(startGridPos, mouseGridPos);
			
			for (int i = 0; i < gridPosList.Count; i++)
			{
				Debug.DrawLine(
					LevelGrid.Instance.GetWorldPos(gridPosList[i]),
					LevelGrid.Instance.GetWorldPos(gridPosList[i + 1]),
					Color.white,
					10f
				);
			}

My code looked like this and when I doublechecked in the resources his testing script included the -1.

Again thanks for looking at this!

1 Like

This topic was automatically closed 24 hours after the last reply. New replies are no longer allowed.

Privacy & Terms