Hello all, I keep getting the error of
ArgumentOutOfRangeException: Specified argument was out of the range of valid values.
Parameter name: Value -1 must be positive.
Unity.Collections.NativeList`1[T].CheckArgInRange (System.Int32 value, System.Int32 length) (at Library/PackageCache/com.unity.collections@0.9.0-preview.6/Unity.Collections/NativeList.cs:783)
Unity.Collections.NativeList`1[T].RemoveAtSwapBack (System.Int32 index) (at Library/PackageCache/com.unity.collections@0.9.0-preview.6/Unity.Collections/NativeList.cs:302)
X1Tools.Unity.Grid.Pathfinding.Advanced.DataOrientedAStar.Execute () (at Assets/Main Assets/Scripts/Enemies/Calculations/DataOrientedAStar.cs:122)
Unity.Jobs.IJobExtensions+JobStruct`1[T].Execute (T& data, System.IntPtr additionalPtr, System.IntPtr bufferRangePatchData, Unity.Jobs.LowLevel.Unsafe.JobRanges& ranges, System.Int32 jobIndex) (at <a979f18d51af41179d12b797e8c5be14>:0)
and I dont know where it’s coming from- any suggestions?
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using Unity.Collections;
using Unity.Jobs;
using Unity.Mathematics;
using UnityEngine;
namespace X1Tools.Unity.Grid.Pathfinding.Advanced
{
public struct DataOrientedAStar : IJob
{
#region Variables
/// <summary>
/// Allows you to use the A* Pathfinding System with Unity Jobs
/// This is much, much faster than the normal A* Pathfinding System.
/// </summary>
//Return type (Redacted until bugs resolved)
// public NativeList<int2> result;
//General inputs
public int2 gridSize;
public NativeList<int2> unwalkableAreas;
//Specific inputs
public int2 origin;
public int2 destination;
#endregion
struct PathNode
{
public int originWeight;
public int destinationWeight;
public int totalWeight;
public int x;
public int y;
public int index;
public int previousNodeIndex;
public void CalculateFCost()
{
totalWeight = originWeight + destinationWeight;
}
}
public void Execute()
{
NativeArray<PathNode> entireGrid = new NativeArray<PathNode>(gridSize.x * gridSize.y, Allocator.Temp);
for (int x = 0; x < gridSize.x; x++)
{
for (int y = 0; y < gridSize.y; y++)
{
PathNode p = new PathNode
{
x = x,
y = y,
index = CalculateIndex(x, y, gridSize.x),
originWeight = CalculateOriginWeight(new int2(x,y)),
destinationWeight = CalculateDestinationWeight(new int2(x, y)),
previousNodeIndex = -1
};
p.CalculateFCost();
entireGrid[p.index] = p;
}
}
PathNode startNode = entireGrid[CalculateIndex(origin.x, origin.y, gridSize.x)];
startNode.originWeight = 0;
startNode.CalculateFCost();
entireGrid[startNode.index] = startNode;
int endNodeIndex = CalculateIndex(destination.x, destination.y, gridSize.x);
NativeList<int> open = new NativeList<int>(Allocator.Temp);
NativeList<int> closed = new NativeList<int>(Allocator.Temp);
open.Add(startNode.index);
while(open.Length > 0)
{
int currentNodeIndex = GetLowestFCostIndex(open,entireGrid);
if (currentNodeIndex == endNodeIndex) { break; }
closed.Add(currentNodeIndex);
open.RemoveAtSwapBack(open.IndexOf(currentNodeIndex));
var surroundingTiles = GetSurroundingTiles(new int2(entireGrid[currentNodeIndex].x, entireGrid[currentNodeIndex].y));
foreach (var i in surroundingTiles)
{
if (!unwalkableAreas.Contains(new int2(entireGrid[i].x, entireGrid[i].y)) && !closed.Contains(i)) { open.Add(i); }
}
surroundingTiles.Dispose();
}
var result = new NativeList<int2>(Allocator.Temp);
int finalNodeIndex = endNodeIndex;
while (!result.Contains(origin))
{
result.Add(new int2(entireGrid[finalNodeIndex].x, entireGrid[finalNodeIndex].y));
closed.RemoveAtSwapBack(closed.IndexOf(finalNodeIndex));
if (finalNodeIndex == startNode.index) { break; }
var f = GetSurroundingTiles(new int2(entireGrid[finalNodeIndex].x, entireGrid[finalNodeIndex].y));
NativeList<int> surroundingClosedTiles = new NativeList<int>(Allocator.Temp);
foreach (var i in f)
{
if (closed.Contains(i)) { surroundingClosedTiles.Add(i); }
}
finalNodeIndex = GetLowestGCostIndex(surroundingClosedTiles, entireGrid);
f.Dispose();
surroundingClosedTiles.Dispose();
}
result.Reverse();
entireGrid.Dispose();
open.Dispose();
closed.Dispose();
//Dispose of until all bugs cleared
result.Dispose();
}
private NativeList<int> GetSurroundingTiles(int2 o)
{
int2 l = o + new int2(1, 0);
int2 lu = o + new int2(1, 1);
int2 ld = o + new int2(1, -1);
int2 c = o + new int2(0, 0);
int2 cu = o + new int2(0, 1);
int2 cd = o + new int2(0, -1);
int2 r = o + new int2(-1, 0);
int2 ru = o + new int2(-1, 1);
int2 rd = o + new int2(-1, -1);
NativeList<int> ret = new NativeList<int>(Allocator.Temp);
if (l.x > gridSize.x || l.y > gridSize.y) { ret.Add(CalculateIndex(l.x, l.y, gridSize.x)); }
if (ld.x > gridSize.x || ld.y > gridSize.y) { ret.Add(CalculateIndex(ld.x, ld.y, gridSize.x)); }
if (lu.x > gridSize.x || lu.y > gridSize.y) { ret.Add(CalculateIndex(lu.x, lu.y, gridSize.x)); }
if (c.x > gridSize.x || c.y > gridSize.y) { ret.Add(CalculateIndex(c.x, c.y, gridSize.x)); }
if (cu.x > gridSize.x || cu.y > gridSize.y) { ret.Add(CalculateIndex(cu.x, cu.y, gridSize.x)); }
if (cd.x > gridSize.x || cd.y > gridSize.y) { ret.Add(CalculateIndex(cd.x, cd.y, gridSize.x)); }
if (r.x > gridSize.x || r.y > gridSize.y) { ret.Add(CalculateIndex(r.x, r.y, gridSize.x)); }
if (ru.x > gridSize.x || ru.y > gridSize.y) { ret.Add(CalculateIndex(ru.x, ru.y, gridSize.x)); }
if (rd.x > gridSize.x || rd.y > gridSize.y) { ret.Add(CalculateIndex(rd.x, rd.y, gridSize.x)); }
return ret;
}
private int CalculateIndex(int x, int y, int gridWidth)
{
return x + y * gridWidth;
}
private int CalculateOriginWeight(int2 location)
{
var x = Mathf.Abs(location.x - origin.x);
var y = Mathf.Abs(location.y - origin.y);
var both = Mathf.Abs(x - y);
return 14 * Mathf.Min(x, y) + 10 * both;
}
private int CalculateDestinationWeight(int2 location)
{
var x = Mathf.Abs(location.x - destination.x);
var y = Mathf.Abs(location.y - destination.y);
var both = Mathf.Abs(x - y);
return 14 * Mathf.Min(x, y) + 10 * both;
}
private int GetLowestFCostIndex(NativeList<int> l,NativeArray<PathNode> h)
{
int currentBestIndex = -1;
int currentBestFCost = -1;
NativeList<PathNode> i = new NativeList<PathNode>(Allocator.Temp);
foreach (var x in h)
{
if (l.Contains(x.index)) { i.Add(x); }
}
foreach (var j in i)
{
if (j.totalWeight > currentBestFCost) { currentBestIndex = j.index; currentBestFCost = j.totalWeight; }
}
i.Dispose();
return currentBestIndex;
}
private int GetLowestGCostIndex(NativeList<int> l, NativeArray<PathNode> h)
{
int currentBestIndex = -1;
int currentBestFCost = int.MaxValue;
NativeList<PathNode> i = new NativeList<PathNode>(Allocator.Temp);
foreach (var x in h)
{
if (l.Contains(x.index)) { i.Add(x); }
}
foreach (var j in i)
{
if (j.originWeight > currentBestFCost) { currentBestIndex = j.index; currentBestFCost = j.originWeight; }
}
i.Dispose();
return currentBestIndex;
}
}
}
Thanks in advance!