Before this lecture everything worked fine. Now I get an error: IndexOutOfRangeExeption: Index was outside of the array.
Can’t seem to find a problem with the code.
It looks like the Pathfinding system is trying to access a node that is not within the Grid System boundary. It’s likely that you need to check to ensure that a location is in the Grid System before accessing it. Paste in your PathFinding.cs method (the text, please, not a screenshot), and we’ll take a look.
Maybe your Enemy is placed outside the Grid? Enable the Grid Debug Visuals to see how big is your grid
All the Units are inside the Grid but I do see a problem with the numbers in the corners? I did notice that the error only happens when I click on the Move button or if the enemy finishes his action.
Hi Brian thnx for your reply. Here’s my Pathfinding.cs
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;
[SerializeField] private LayerMask obstaclesLayerMask;
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;
}
public void SetUp(int width, int height, float cellSize)
{
this.width = width;
this.height = height;
this.cellSize = cellSize;
gridSystem = new GridSystem<PathNode>(width, height, cellSize,
(GridSystem<PathNode> g, GridPosition gridPosition) => new PathNode(gridPosition));
gridSystem.CreateDebugObjects(gridDebugObjectPrefab);
for (int x = 0; x < width; x++)
{
for (int z = 0; z < height; z++)
{
GridPosition gridPosition = new GridPosition(x, z);
Vector3 worldPosition = LevelGrid.Instance.GetWorldPosition(gridPosition);
float raycastOffsetDistance = 5f;
if (Physics.Raycast(
worldPosition + Vector3.down * raycastOffsetDistance,
Vector3.up,
raycastOffsetDistance * 2,
obstaclesLayerMask))
{
GetNode(x, z).SetIsWalkable(false);
}
}
}
}
public List<GridPosition> FindPath(GridPosition startGridPosition, GridPosition endGridPosition, out int pathLength)
{
List<PathNode> openList = new List<PathNode>();
List<PathNode> closedList = new List<PathNode>();
PathNode startNode = gridSystem.GetGridObject(startGridPosition);
PathNode endNode = gridSystem.GetGridObject(endGridPosition);
openList.Add(startNode);
for (int x = 0; x < gridSystem.GetWidth(); x++)
{
for (int z = 0; z < gridSystem.GetHeight(); z++)
{
GridPosition gridPosition = new GridPosition(x, z);
PathNode pathNode = gridSystem.GetGridObject(gridPosition);
pathNode.SetGCost(int.MaxValue);
pathNode.SetHCost(0);
pathNode.CalculateFCost();
pathNode.ResetCameFromPathNode();
}
}
startNode.SetGCost(0);
startNode.SetHCost(CalculateDistance(startGridPosition, endGridPosition));
startNode.CalculateFCost();
while (openList.Count > 0)
{
PathNode currentNode = GetLowestFCostPathNode(openList);
if (currentNode == endNode)
{
// Reached final node
pathLength = endNode.GetFCost();
return CalculatePath(endNode);
}
openList.Remove(currentNode);
closedList.Add(currentNode);
foreach (PathNode neighbourNode in GetNeighbourList(currentNode))
{
if (closedList.Contains(neighbourNode))
{
continue;
}
if (!neighbourNode.IsWalkable())
{
closedList.Add(neighbourNode);
continue;
}
int tentativeGCost =
currentNode.GetGCost() + CalculateDistance(currentNode.GetGridPosition(), neighbourNode.GetGridPosition());
if(tentativeGCost < neighbourNode.GetGCost())
{
neighbourNode.SetCameFromPathNode(currentNode);
neighbourNode.SetGCost(tentativeGCost);
neighbourNode.SetHCost(CalculateDistance(neighbourNode.GetGridPosition(), endGridPosition));
neighbourNode.CalculateFCost();
if (!openList.Contains(neighbourNode))
{
openList.Add(neighbourNode);
}
}
}
}
// No path found
pathLength = 0;
return null;
}
public int CalculateDistance(GridPosition gridPositionA, GridPosition gridPositionB)
{
GridPosition gridPositionDistance = gridPositionA - gridPositionB;
int xDistance = Mathf.Abs(gridPositionDistance.x);
int zDistance = Mathf.Abs(gridPositionDistance.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)
{
return gridSystem.GetGridObject(new GridPosition(x, z));
}
private List<PathNode> GetNeighbourList(PathNode currentNode)
{
List<PathNode> neighbourList = new List<PathNode>();
GridPosition gridPosition = currentNode.GetGridPosition();
if (gridPosition.x - 1 >= 0)
{// left
neighbourList.Add(GetNode(gridPosition.x - 1, gridPosition.z + 0));
if (gridPosition.z - 1 >= 0)
{
// left Down
neighbourList.Add(GetNode(gridPosition.x - 1, gridPosition.z + -1));
}
if (gridPosition.z + 1 < gridSystem.GetHeight())
{
// left Up
neighbourList.Add(GetNode(gridPosition.x - 1, gridPosition.z + +1));
}
}
if (gridPosition.x + 1 < gridSystem.GetWidth())
{// Right
neighbourList.Add(GetNode(gridPosition.x + 1, gridPosition.z + 0));
if (gridPosition.z - 1 >= 0)
{
// Right Down
neighbourList.Add(GetNode(gridPosition.x + 1, gridPosition.z - 1));
}
if (gridPosition.z +1 < gridSystem.GetHeight())
{
// Right Up
neighbourList.Add(GetNode(gridPosition.x + 1, gridPosition.z + 1));
}
}
if (gridPosition.z - 1 >= 0)
{
// Down
neighbourList.Add(GetNode(gridPosition.x + 1, gridPosition.z - 1));
}
if (gridPosition.z + 1 < gridSystem.GetHeight())
{
// Up
neighbourList.Add(GetNode(gridPosition.x + 1, gridPosition.z + 1));
}
return neighbourList;
}
private List<GridPosition> 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<GridPosition> gridPositionList = new List<GridPosition>();
foreach (PathNode pathNode in pathNodeList)
{
gridPositionList.Add(pathNode.GetGridPosition());
}
return gridPositionList;
}
public bool IsWalkableGridPosition(GridPosition gridPosition)
{
return gridSystem.GetGridObject(gridPosition).IsWalkable();
}
public bool HasPath(GridPosition startGridPosition, GridPosition endGridPosition)
{
return FindPath(startGridPosition, endGridPosition, out int pathLength) != null;
}
public int GetPathLength(GridPosition startGridPosition, GridPosition endGridPosition)
{
FindPath(startGridPosition, endGridPosition, out int pathLength);
return pathLength;
}
}
I’m so dumb haha found the error. it was in this line of code Instead of gridposition.x +0. I had +1
{
// Down
neighbourList.Add(GetNode(gridPosition.x + 0, gridPosition.z - 1));
}
if (gridPosition.z + 1 < gridSystem.GetHeight())
{
// Up
neighbourList.Add(GetNode(gridPosition.x + 0, gridPosition.z + 1));
}
You’re so smart, you found it before I got a chance to go through the code. Good job!
Hello everyone,
happy new years all !
I had the same message.
But for me it was my level size which didn’t match with my real level size.
I’ve put 21x18x2 and after recompute the size I needed 25x21x2.
Everything work fine now.
Thanks
François