Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.

ArgumentOutOfRangeException for Native Lists

Discussion in 'Scripting' started by lewisjet, Oct 2, 2020.

  1. lewisjet

    lewisjet

    Joined:
    Apr 27, 2020
    Posts:
    9
    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?

    Code (CSharp):
    1. using System.Collections;
    2. using System.Collections.Generic;
    3. using System.Linq;
    4. using Unity.Collections;
    5. using Unity.Jobs;
    6. using Unity.Mathematics;
    7. using UnityEngine;
    8.  
    9. namespace X1Tools.Unity.Grid.Pathfinding.Advanced
    10. {
    11.  
    12.     public struct DataOrientedAStar : IJob
    13.     {
    14.         #region Variables
    15.  
    16.         /// <summary>
    17.         /// Allows you to use the A* Pathfinding System with Unity Jobs
    18.         /// This is much, much faster than the normal A* Pathfinding System.
    19.         /// </summary>
    20.  
    21.         //Return type (Redacted until bugs resolved)
    22.        // public NativeList<int2> result;
    23.        
    24.  
    25.         //General inputs
    26.         public int2 gridSize;
    27.         public NativeList<int2> unwalkableAreas;
    28.  
    29.         //Specific inputs
    30.         public int2 origin;
    31.         public int2 destination;
    32.  
    33.         #endregion
    34.  
    35.         struct PathNode
    36.         {
    37.             public int originWeight;
    38.             public int destinationWeight;
    39.             public int totalWeight;
    40.  
    41.             public int x;
    42.             public int y;
    43.  
    44.             public int index;
    45.             public int previousNodeIndex;
    46.  
    47.             public void CalculateFCost()
    48.             {
    49.                 totalWeight = originWeight + destinationWeight;
    50.             }
    51.         }
    52.  
    53.         public void Execute()
    54.         {
    55.             NativeArray<PathNode> entireGrid = new NativeArray<PathNode>(gridSize.x * gridSize.y, Allocator.Temp);
    56.  
    57.             for (int x = 0; x < gridSize.x; x++)
    58.             {
    59.                 for (int y = 0; y < gridSize.y; y++)
    60.                 {
    61.                     PathNode p = new PathNode
    62.                     {
    63.                         x = x,
    64.                         y = y,
    65.  
    66.                         index = CalculateIndex(x, y, gridSize.x),
    67.  
    68.                         originWeight = CalculateOriginWeight(new int2(x,y)),
    69.                         destinationWeight = CalculateDestinationWeight(new int2(x, y)),
    70.  
    71.                         previousNodeIndex = -1
    72.                 };
    73.  
    74.                     p.CalculateFCost();
    75.  
    76.                     entireGrid[p.index] = p;
    77.  
    78.                 }
    79.             }
    80.  
    81.             PathNode startNode = entireGrid[CalculateIndex(origin.x, origin.y, gridSize.x)];
    82.             startNode.originWeight = 0;
    83.             startNode.CalculateFCost();
    84.             entireGrid[startNode.index] = startNode;
    85.  
    86.             int endNodeIndex = CalculateIndex(destination.x, destination.y, gridSize.x);
    87.  
    88.             NativeList<int> open = new NativeList<int>(Allocator.Temp);
    89.             NativeList<int> closed = new NativeList<int>(Allocator.Temp);
    90.  
    91.             open.Add(startNode.index);
    92.  
    93.             while(open.Length > 0)
    94.             {
    95.                 int currentNodeIndex = GetLowestFCostIndex(open,entireGrid);
    96.                 if (currentNodeIndex == endNodeIndex) { break; }
    97.  
    98.                 closed.Add(currentNodeIndex);
    99.  
    100.                     open.RemoveAtSwapBack(open.IndexOf(currentNodeIndex));
    101.                
    102.  
    103.                 var surroundingTiles = GetSurroundingTiles(new int2(entireGrid[currentNodeIndex].x, entireGrid[currentNodeIndex].y));
    104.                
    105.                 foreach (var i in surroundingTiles)
    106.                 {
    107.                     if (!unwalkableAreas.Contains(new int2(entireGrid[i].x, entireGrid[i].y)) && !closed.Contains(i)) { open.Add(i); }
    108.                 }
    109.                 surroundingTiles.Dispose();
    110.                
    111.             }
    112.  
    113.            var result = new NativeList<int2>(Allocator.Temp);
    114.  
    115.             int finalNodeIndex = endNodeIndex;
    116.             while (!result.Contains(origin))
    117.             {
    118.                 result.Add(new int2(entireGrid[finalNodeIndex].x, entireGrid[finalNodeIndex].y));
    119.  
    120.                     closed.RemoveAtSwapBack(closed.IndexOf(finalNodeIndex));
    121.                
    122.                 if (finalNodeIndex == startNode.index) { break; }
    123.  
    124.                 var f = GetSurroundingTiles(new int2(entireGrid[finalNodeIndex].x, entireGrid[finalNodeIndex].y));
    125.  
    126.                 NativeList<int> surroundingClosedTiles = new NativeList<int>(Allocator.Temp);
    127.  
    128.                 foreach (var i in f)
    129.                 {
    130.                     if (closed.Contains(i)) { surroundingClosedTiles.Add(i); }
    131.                 }
    132.  
    133.                 finalNodeIndex = GetLowestGCostIndex(surroundingClosedTiles, entireGrid);
    134.                 f.Dispose();
    135.                 surroundingClosedTiles.Dispose();
    136.             }
    137.  
    138.             result.Reverse();
    139.  
    140.             entireGrid.Dispose();
    141.             open.Dispose();
    142.             closed.Dispose();
    143.  
    144.             //Dispose of until all bugs cleared
    145.             result.Dispose();
    146.  
    147.         }
    148.  
    149.         private NativeList<int> GetSurroundingTiles(int2 o)
    150.         {
    151.  
    152.             int2 l = o + new int2(1, 0);
    153.             int2 lu = o + new int2(1, 1);
    154.             int2 ld = o + new int2(1, -1);
    155.             int2 c = o + new int2(0, 0);
    156.             int2 cu = o + new int2(0, 1);
    157.             int2 cd = o + new int2(0, -1);
    158.             int2 r = o + new int2(-1, 0);
    159.             int2 ru = o + new int2(-1, 1);
    160.             int2 rd = o + new int2(-1, -1);
    161.  
    162.             NativeList<int> ret = new NativeList<int>(Allocator.Temp);
    163.  
    164.             if (l.x > gridSize.x || l.y > gridSize.y) { ret.Add(CalculateIndex(l.x, l.y, gridSize.x)); }
    165.             if (ld.x > gridSize.x || ld.y > gridSize.y) { ret.Add(CalculateIndex(ld.x, ld.y, gridSize.x)); }
    166.             if (lu.x > gridSize.x || lu.y > gridSize.y) { ret.Add(CalculateIndex(lu.x, lu.y, gridSize.x)); }
    167.             if (c.x > gridSize.x || c.y > gridSize.y) { ret.Add(CalculateIndex(c.x, c.y, gridSize.x)); }
    168.             if (cu.x > gridSize.x || cu.y > gridSize.y) { ret.Add(CalculateIndex(cu.x, cu.y, gridSize.x)); }
    169.             if (cd.x > gridSize.x || cd.y > gridSize.y) { ret.Add(CalculateIndex(cd.x, cd.y, gridSize.x)); }
    170.             if (r.x > gridSize.x || r.y > gridSize.y) { ret.Add(CalculateIndex(r.x, r.y, gridSize.x)); }
    171.             if (ru.x > gridSize.x || ru.y > gridSize.y) { ret.Add(CalculateIndex(ru.x, ru.y, gridSize.x)); }
    172.             if (rd.x > gridSize.x || rd.y > gridSize.y) { ret.Add(CalculateIndex(rd.x, rd.y, gridSize.x)); }
    173.  
    174.             return ret;
    175.         }
    176.  
    177.         private int CalculateIndex(int x, int y, int gridWidth)
    178.         {
    179.             return x + y * gridWidth;
    180.         }
    181.  
    182.         private int CalculateOriginWeight(int2 location)
    183.         {
    184.             var x = Mathf.Abs(location.x - origin.x);
    185.             var y = Mathf.Abs(location.y - origin.y);
    186.             var both = Mathf.Abs(x - y);
    187.             return 14 * Mathf.Min(x, y) + 10 * both;
    188.         }
    189.  
    190.         private int CalculateDestinationWeight(int2 location)
    191.         {
    192.             var x = Mathf.Abs(location.x - destination.x);
    193.             var y = Mathf.Abs(location.y - destination.y);
    194.             var both = Mathf.Abs(x - y);
    195.             return 14 * Mathf.Min(x, y) + 10 * both;
    196.         }
    197.  
    198.         private int GetLowestFCostIndex(NativeList<int> l,NativeArray<PathNode> h)
    199.         {
    200.  
    201.             int currentBestIndex = -1;
    202.             int currentBestFCost = -1;
    203.  
    204.             NativeList<PathNode> i = new NativeList<PathNode>(Allocator.Temp);
    205.             foreach (var x in h)
    206.             {
    207.                 if (l.Contains(x.index)) { i.Add(x); }
    208.             }
    209.  
    210.             foreach (var j in i)
    211.             {
    212.                 if (j.totalWeight > currentBestFCost) { currentBestIndex = j.index; currentBestFCost = j.totalWeight; }
    213.             }
    214.  
    215.             i.Dispose();
    216.             return currentBestIndex;
    217.         }
    218.         private int GetLowestGCostIndex(NativeList<int> l, NativeArray<PathNode> h)
    219.         {
    220.  
    221.             int currentBestIndex = -1;
    222.             int currentBestFCost = int.MaxValue;
    223.  
    224.             NativeList<PathNode> i = new NativeList<PathNode>(Allocator.Temp);
    225.             foreach (var x in h)
    226.             {
    227.                 if (l.Contains(x.index)) { i.Add(x); }
    228.             }
    229.  
    230.             foreach (var j in i)
    231.             {
    232.                 if (j.originWeight > currentBestFCost) { currentBestIndex = j.index; currentBestFCost = j.originWeight; }
    233.             }
    234.  
    235.             i.Dispose();
    236.             return currentBestIndex;
    237.         }
    238.     }
    239. }
    Thanks in advance!
     
  2. Sphinks

    Sphinks

    Joined:
    Apr 6, 2019
    Posts:
    267
    The problem is, that the error comes from the the NativeList, but it looks like, that you return -1 in your "GetLowestFCostIndex", but an Index (of a list) can not be negative. Can you check which value is returned on that method?
     
  3. lewisjet

    lewisjet

    Joined:
    Apr 27, 2020
    Posts:
    9
    Hmm.. I changed it's default index to 0, on the GetLowestFCostIndex, and it's GCost counterpart, but it's still got the same error.

    My new code is:
    Code (CSharp):
    1. using System.Collections;
    2. using System.Collections.Generic;
    3. using System.Linq;
    4. using Unity.Collections;
    5. using Unity.Jobs;
    6. using Unity.Mathematics;
    7. using UnityEngine;
    8.  
    9. namespace X1Tools.Unity.Grid.Pathfinding.Advanced
    10. {
    11.  
    12.     public struct DataOrientedAStar : IJob
    13.     {
    14.         #region Variables
    15.  
    16.         /// <summary>
    17.         /// Allows you to use the A* Pathfinding System with Unity Jobs
    18.         /// This is much, much faster than the normal A* Pathfinding System.
    19.         /// </summary>
    20.  
    21.         //Return type (Redacted until bugs resolved)
    22.        // public NativeList<int2> result;
    23.        
    24.  
    25.         //General inputs
    26.         public int2 gridSize;
    27.         public NativeList<int2> unwalkableAreas;
    28.  
    29.         //Specific inputs
    30.         public int2 origin;
    31.         public int2 destination;
    32.  
    33.         #endregion
    34.  
    35.         struct PathNode
    36.         {
    37.             public int originWeight;
    38.             public int destinationWeight;
    39.             public int totalWeight;
    40.  
    41.             public int x;
    42.             public int y;
    43.  
    44.             public int index;
    45.         //    public int previousNodeIndex;
    46.  
    47.             public void CalculateFCost()
    48.             {
    49.                 totalWeight = originWeight + destinationWeight;
    50.             }
    51.         }
    52.  
    53.         public void Execute()
    54.         {
    55.             NativeArray<PathNode> entireGrid = new NativeArray<PathNode>(gridSize.x * gridSize.y, Allocator.Temp);
    56.  
    57.             for (int x = 0; x < gridSize.x; x++)
    58.             {
    59.                 for (int y = 0; y < gridSize.y; y++)
    60.                 {
    61.                     PathNode p = new PathNode
    62.                     {
    63.                         x = x,
    64.                         y = y,
    65.  
    66.                         index = CalculateIndex(x, y, gridSize.x),
    67.  
    68.                         originWeight = CalculateOriginWeight(new int2(x,y)),
    69.                         destinationWeight = CalculateDestinationWeight(new int2(x, y)),
    70.  
    71.                      //   previousNodeIndex = -1
    72.                 };
    73.  
    74.                     p.CalculateFCost();
    75.  
    76.                     entireGrid[p.index] = p;
    77.  
    78.                 }
    79.             }
    80.  
    81.             PathNode startNode = entireGrid[CalculateIndex(origin.x, origin.y, gridSize.x)];
    82.             startNode.originWeight = 0;
    83.             startNode.CalculateFCost();
    84.             entireGrid[startNode.index] = startNode;
    85.  
    86.             int endNodeIndex = CalculateIndex(destination.x, destination.y, gridSize.x);
    87.  
    88.             NativeList<int> open = new NativeList<int>(Allocator.Temp);
    89.             NativeList<int> closed = new NativeList<int>(Allocator.Temp);
    90.  
    91.             open.Add(startNode.index);
    92.  
    93.             while(open.Length > 0)
    94.             {
    95.                 int currentNodeIndex = GetLowestFCostIndex(open,entireGrid);
    96.                 if (currentNodeIndex == endNodeIndex) { break; }
    97.  
    98.                 closed.Add(currentNodeIndex);
    99.  
    100.                     open.RemoveAtSwapBack(open.IndexOf(currentNodeIndex));
    101.                
    102.  
    103.                 var surroundingTiles = GetSurroundingTiles(new int2(entireGrid[currentNodeIndex].x, entireGrid[currentNodeIndex].y));
    104.                
    105.                 foreach (var i in surroundingTiles)
    106.                 {
    107.                     if (!unwalkableAreas.Contains(new int2(entireGrid[i].x, entireGrid[i].y)) && !closed.Contains(i)) { open.Add(i); }
    108.                 }
    109.                 surroundingTiles.Dispose();
    110.                
    111.             }
    112.  
    113.            var result = new NativeList<int2>(Allocator.Temp);
    114.  
    115.             int finalNodeIndex = endNodeIndex;
    116.             while (!result.Contains(origin))
    117.             {
    118.                 result.Add(new int2(entireGrid[finalNodeIndex].x, entireGrid[finalNodeIndex].y));
    119.  
    120.                     closed.RemoveAtSwapBack(closed.IndexOf(finalNodeIndex));
    121.                
    122.                 if (finalNodeIndex == startNode.index) { break; }
    123.  
    124.                 var f = GetSurroundingTiles(new int2(entireGrid[finalNodeIndex].x, entireGrid[finalNodeIndex].y));
    125.  
    126.                 NativeList<int> surroundingClosedTiles = new NativeList<int>(Allocator.Temp);
    127.  
    128.                 foreach (var i in f)
    129.                 {
    130.                     if (closed.Contains(i)) { surroundingClosedTiles.Add(i); }
    131.                 }
    132.  
    133.                 finalNodeIndex = GetLowestGCostIndex(surroundingClosedTiles, entireGrid);
    134.                 f.Dispose();
    135.                 surroundingClosedTiles.Dispose();
    136.             }
    137.  
    138.             result.Reverse();
    139.  
    140.             entireGrid.Dispose();
    141.             open.Dispose();
    142.             closed.Dispose();
    143.  
    144.             //Dispose of until all bugs cleared
    145.             result.Dispose();
    146.  
    147.         }
    148.  
    149.         private NativeList<int> GetSurroundingTiles(int2 o)
    150.         {
    151.  
    152.             int2 l = o + new int2(1, 0);
    153.             int2 lu = o + new int2(1, 1);
    154.             int2 ld = o + new int2(1, -1);
    155.             int2 c = o + new int2(0, 0);
    156.             int2 cu = o + new int2(0, 1);
    157.             int2 cd = o + new int2(0, -1);
    158.             int2 r = o + new int2(-1, 0);
    159.             int2 ru = o + new int2(-1, 1);
    160.             int2 rd = o + new int2(-1, -1);
    161.  
    162.             NativeList<int> ret = new NativeList<int>(Allocator.Temp);
    163.  
    164.             if (l.x > gridSize.x || l.y > gridSize.y) { ret.Add(CalculateIndex(l.x, l.y, gridSize.x)); }
    165.             if (ld.x > gridSize.x || ld.y > gridSize.y) { ret.Add(CalculateIndex(ld.x, ld.y, gridSize.x)); }
    166.             if (lu.x > gridSize.x || lu.y > gridSize.y) { ret.Add(CalculateIndex(lu.x, lu.y, gridSize.x)); }
    167.             if (c.x > gridSize.x || c.y > gridSize.y) { ret.Add(CalculateIndex(c.x, c.y, gridSize.x)); }
    168.             if (cu.x > gridSize.x || cu.y > gridSize.y) { ret.Add(CalculateIndex(cu.x, cu.y, gridSize.x)); }
    169.             if (cd.x > gridSize.x || cd.y > gridSize.y) { ret.Add(CalculateIndex(cd.x, cd.y, gridSize.x)); }
    170.             if (r.x > gridSize.x || r.y > gridSize.y) { ret.Add(CalculateIndex(r.x, r.y, gridSize.x)); }
    171.             if (ru.x > gridSize.x || ru.y > gridSize.y) { ret.Add(CalculateIndex(ru.x, ru.y, gridSize.x)); }
    172.             if (rd.x > gridSize.x || rd.y > gridSize.y) { ret.Add(CalculateIndex(rd.x, rd.y, gridSize.x)); }
    173.  
    174.             return ret;
    175.         }
    176.  
    177.         private int CalculateIndex(int x, int y, int gridWidth)
    178.         {
    179.             return x + y * gridWidth;
    180.         }
    181.  
    182.         private int CalculateOriginWeight(int2 location)
    183.         {
    184.             var x = Mathf.Abs(location.x - origin.x);
    185.             var y = Mathf.Abs(location.y - origin.y);
    186.             var both = Mathf.Abs(x - y);
    187.             return 14 * Mathf.Min(x, y) + 10 * both;
    188.         }
    189.  
    190.         private int CalculateDestinationWeight(int2 location)
    191.         {
    192.             var x = Mathf.Abs(location.x - destination.x);
    193.             var y = Mathf.Abs(location.y - destination.y);
    194.             var both = Mathf.Abs(x - y);
    195.             return 14 * Mathf.Min(x, y) + 10 * both;
    196.         }
    197.  
    198.         private int GetLowestFCostIndex(NativeList<int> l,NativeArray<PathNode> h)
    199.         {
    200.  
    201.             int currentBestIndex = 0;
    202.             int currentBestFCost = 0;
    203.  
    204.             NativeList<PathNode> i = new NativeList<PathNode>(Allocator.Temp);
    205.             foreach (var x in h)
    206.             {
    207.                 if (l.Contains(x.index)) { i.Add(x); }
    208.             }
    209.  
    210.             foreach (var j in i)
    211.             {
    212.                 if (j.totalWeight > currentBestFCost) { currentBestIndex = j.index; currentBestFCost = j.totalWeight; }
    213.             }
    214.  
    215.             i.Dispose();
    216.             return currentBestIndex;
    217.         }
    218.         private int GetLowestGCostIndex(NativeList<int> l, NativeArray<PathNode> h)
    219.         {
    220.  
    221.             int currentBestIndex = 0;
    222.             int currentBestFCost = int.MaxValue;
    223.  
    224.             NativeList<PathNode> i = new NativeList<PathNode>(Allocator.Temp);
    225.             foreach (var x in h)
    226.             {
    227.                 if (l.Contains(x.index)) { i.Add(x); }
    228.             }
    229.  
    230.             foreach (var j in i)
    231.             {
    232.                 if (j.originWeight > currentBestFCost) { currentBestIndex = j.index; currentBestFCost = j.originWeight; }
    233.             }
    234.  
    235.             i.Dispose();
    236.             return currentBestIndex;
    237.         }
    238.     }
    239. }
     
  4. Sphinks

    Sphinks

    Joined:
    Apr 6, 2019
    Posts:
    267
    Can you check, what the value for startNode.index from line 122 is ? Just put a Debug.Log(startNode.index) before.
     
  5. lewisjet

    lewisjet

    Joined:
    Apr 27, 2020
    Posts:
    9
    I put in the Debug.Log, on line 121, and it didn't output anything, strangely. This means that the error is before that point. When i put the Debug.Log on line 85, I got the index(s) of all of my enemies positions (the origin is the enemies vector 2 position, as an int2):
    • 1799
    • 626
    • 2168
    • 739
    • 1630
    • 1926
    • 325
    • 734
    Note: this code is running through the Job system, meaning that it's threaded.
     
  6. Sphinks

    Sphinks

    Joined:
    Apr 6, 2019
    Posts:
    267
    Hmm ok, cause on the error messages it says:
    "X1Tools.Unity.Grid.Pathfinding.Advanced.DataOrientedAStar.Execute () (at Assets/Main Assets/Scripts/Enemies/Calculations/DataOrientedAStar.cs:122)"

    But how can that be, if it doesn´t reach line 122 ? Ok sry, then i have no idea. Any1 with better knowladge has to look here.

    The only thing i can say is, that i would put more logs in the script, to figure out on which line it fails and check the values that are used there.
     
  7. lewisjet

    lewisjet

    Joined:
    Apr 27, 2020
    Posts:
    9
    Line 122 is in the execute function
     
  8. lewisjet

    lewisjet

    Joined:
    Apr 27, 2020
    Posts:
    9
    I made a mistake, Sphinks- it's from 125-148...
    Nonetheless, I've fixed the issue now- thanks for the help!
    However, now it gets stuck in an indefinite for loop...
     
    Last edited: Oct 2, 2020
    Joe-Censored and Sphinks like this.