Search Unity

  1. Megacity Metro Demo now available. Download now.
    Dismiss Notice
  2. Unity support for visionOS is now available. Learn more in our blog post.
    Dismiss Notice

IndexOutOfRangeException: Index out of bounds of the Array?

Discussion in 'Scripting' started by JohnnysSoftwares, Jan 4, 2020.

  1. JohnnysSoftwares

    JohnnysSoftwares

    Joined:
    Mar 16, 2016
    Posts:
    11
    Hi, it is me again. So I recieved this error with my code:
    IndexOutOfRangeException: Index was outside the bounds of the array.
    Chunk.CheckVoxel (UnityEngine.Vector3 pos) (at Assets/Scripts/C#/Chunk.cs:59)
    Chunk.AddVoxelDataToChunk (UnityEngine.Vector3 pos) (at Assets/Scripts/C#/Chunk.cs:64)
    Chunk.CreateMeshData () (at Assets/Scripts/C#/Chunk.cs:45)
    Chunk.Start () (at Assets/Scripts/C#/Chunk.cs:22)

    I have looked at my code here:
    Code (CSharp):
    1. using System.Collections;
    2. using System.Collections.Generic;
    3. using UnityEngine;
    4.  
    5. public class Chunk : MonoBehaviour
    6. {
    7.     public MeshRenderer meshRenderer;
    8.     public MeshFilter meshFilter;
    9.    
    10.     int vertexIndex = 0;
    11.     List<Vector3> vertices = new List<Vector3> ();
    12.     List<int> triangles = new List<int> ();
    13.     List<Vector2> uvs = new List<Vector2> ();
    14.    
    15.     byte[,,] voxelMap = new byte[VoxelData.ChunkWidth, VoxelData.ChunkHeight, VoxelData.ChunkWidth];
    16.    
    17.     World world;
    18.    
    19.     void Start () {
    20.         world = GameObject.Find("World").GetComponent<World>();
    21.         PopulateVoxelMap ();
    22.         CreateMeshData ();
    23.         CreateMesh ();
    24.     }
    25.    
    26.     void PopulateVoxelMap () {
    27.         for (int y = 0; y < VoxelData.ChunkHeight; y++) {
    28.             for (int x = 0; x < VoxelData.ChunkWidth; x++) {
    29.                 for (int z = 0; z < VoxelData.ChunkWidth; z++) {
    30.                         if (y < 1)
    31.                             voxelMap[x, y, z] = 0;
    32.                         else if (y == VoxelData.ChunkHeight - 1)
    33.                             voxelMap[x, y, z] = 3;
    34.                         else
    35.                             voxelMap[x, y, z] = 1;
    36.                 }
    37.             }
    38.         }
    39.     }
    40.    
    41.     void CreateMeshData () {
    42.         for (int y = 0; y < VoxelData.ChunkHeight; y++) {
    43.             for (int x = 0; x < VoxelData.ChunkWidth; x++) {
    44.                 for (int z = 0; z < VoxelData.ChunkWidth; z++) {
    45.                         AddVoxelDataToChunk (new Vector3(x, y, z));
    46.                 }
    47.             }
    48.         }
    49.     }
    50.    
    51.     bool CheckVoxel (Vector3 pos) {
    52.         int x = Mathf.FloorToInt (pos.x);
    53.         int y = Mathf.FloorToInt (pos.y);
    54.         int z = Mathf.FloorToInt (pos.z);
    55.        
    56.         if (x < 0 || x > VoxelData.ChunkWidth - 1 || y < 0 || y > VoxelData.ChunkHeight - 1 || z < 0 || z > VoxelData.ChunkWidth - 1) {
    57.             return false;
    58.         }
    59.         return world.blocktypes[voxelMap[x, y, z]].isSolid;
    60.     }
    61.    
    62.     void AddVoxelDataToChunk (Vector3 pos) {
    63.         for (int p = 0; p < 6; p++) {
    64.             if(!CheckVoxel(pos + VoxelData.faceChecks[p])) {
    65.                 byte blockID = voxelMap[(int)pos.x, (int)pos.y, (int)pos.z];
    66.                 vertices.Add (pos + VoxelData.voxelVerts [VoxelData.voxelTris [p, 0]]);
    67.                 vertices.Add (pos + VoxelData.voxelVerts [VoxelData.voxelTris [p, 1]]);
    68.                 vertices.Add (pos + VoxelData.voxelVerts [VoxelData.voxelTris [p, 2]]);
    69.                 vertices.Add (pos + VoxelData.voxelVerts [VoxelData.voxelTris [p, 3]]);
    70.                 AddTexture(world.blocktypes[blockID].GetTextureID(p));
    71.                 triangles.Add (vertexIndex);
    72.                 triangles.Add (vertexIndex + 1);
    73.                 triangles.Add (vertexIndex + 2);
    74.                 triangles.Add (vertexIndex + 2);
    75.                 triangles.Add (vertexIndex + 1);
    76.                 triangles.Add (vertexIndex + 3);
    77.                 vertexIndex += 4;
    78.             }
    79.         }
    80.     }
    81.    
    82.     void CreateMesh () {
    83.         Mesh mesh = new Mesh ();
    84.         mesh.vertices = vertices.ToArray ();
    85.         mesh.triangles = triangles.ToArray ();
    86.         mesh.uv = uvs.ToArray ();
    87.        
    88.         mesh.RecalculateNormals ();
    89.        
    90.         meshFilter.mesh = mesh;
    91.     }
    92.    
    93.     void AddTexture (int textureID) {
    94.         float y = textureID / VoxelData.TextureAtlasSizeInBlocks;
    95.         float x = textureID % VoxelData.TextureAtlasSizeInBlocks;
    96.        
    97.         x *= VoxelData.NormalizedBlockTextureSize;
    98.         y *= VoxelData.NormalizedBlockTextureSize;
    99.        
    100.         y = 1f - y - VoxelData.NormalizedBlockTextureSize;
    101.  
    102.         uvs.Add (new Vector2(x, y));
    103.         uvs.Add (new Vector2(x, y + VoxelData.NormalizedBlockTextureSize));
    104.         uvs.Add (new Vector2(x + VoxelData.NormalizedBlockTextureSize, y));
    105.         uvs.Add (new Vector2(x + VoxelData.NormalizedBlockTextureSize, y + VoxelData.NormalizedBlockTextureSize));
    106.     }
    107. }
    And here is my voxel Data Script:

    Code (CSharp):
    1. using System.Collections;
    2. using System.Collections.Generic;
    3. using UnityEngine;
    4.  
    5. public class VoxelData
    6. {
    7.     public static readonly int ChunkWidth = 5;
    8.     public static readonly int ChunkHeight = 15;
    9.     public static readonly int TextureAtlasSizeInBlocks = 4;
    10.    
    11.     public static float NormalizedBlockTextureSize {
    12.         get { return 1f / (float)TextureAtlasSizeInBlocks; }
    13.     }
    14.    
    15.     public static readonly Vector3[] voxelVerts = new Vector3[8] {
    16.         // Represents Location of Vertices in the Cube (Voxel)
    17.         new Vector3(0.0f, 0.0f, 0.0f),
    18.         new Vector3(1.0f, 0.0f, 0.0f),
    19.         new Vector3(1.0f, 1.0f, 0.0f),
    20.         new Vector3(0.0f, 1.0f, 0.0f),
    21.         new Vector3(0.0f, 0.0f, 1.0f),
    22.         new Vector3(1.0f, 0.0f, 1.0f),
    23.         new Vector3(1.0f, 1.0f, 1.0f),
    24.         new Vector3(0.0f, 1.0f, 1.0f),
    25.     };
    26.    
    27.     public static readonly Vector3[] faceChecks = new Vector3[6] {
    28.         new Vector3(0.0f, 0.0f, -1.0f),
    29.         new Vector3(0.0f, 0.0f, 1.0f),
    30.         new Vector3(0.0f, 1.0f, 0.0f),
    31.         new Vector3(0.0f, -1.0f, 0.0f),
    32.         new Vector3(-1.0f, 0.0f, 0.0f),
    33.         new Vector3(1.0f, 0.0f, 0.0f),
    34.     };
    35.    
    36.     public static readonly int[,] voxelTris = new int[6,4] {
    37.         // Represents the Voxel Triangle Faces
    38.         // 0 1 2 2 1 3
    39.         {0, 3, 1, 2}, // Back Face
    40.         {5, 6, 4, 7}, // Front Face
    41.         {3, 7, 2, 6}, // Top Face
    42.         {1, 5, 0, 4}, // Bottom Face
    43.         {4, 7, 0, 3}, // Left Face
    44.         {1, 2, 5, 6}, // Right Face
    45.     };
    46.    
    47.     public static readonly Vector2[] voxelUvs = new Vector2[4] {
    48.         new Vector2 (0.0f, 0.0f),
    49.         new Vector2 (0.0f, 1.0f),
    50.         new Vector2 (1.0f, 0.0f),
    51.         new Vector2 (1.0f, 1.0f),
    52.     };
    53. }
    I was using a tutorial and referencing his scripts but it appears I have reached an issue. I am sure I missed something but I haven't been able to find where I messed up.

    Here is where the YouTube Content Creators scripts are:
    https://github.com/b3agz/Code-A-Game-Like-Minecraft-In-Unity/tree/master/03-texturing/Assets/Scripts

    So did I miss something or is the problem elsewhere? I have one other script but I doubt it is in there.

    Thanks ahead of time.
     
  2. Kurt-Dekker

    Kurt-Dekker

    Joined:
    Mar 16, 2013
    Posts:
    38,520
    If line 59 in the first script is where you are getting the error, I see that it contains two nested dereferences.

    First you get the Voxel x,y,z, which is perhaps okay since you guard it beforehand, but then you use the value to unquestioningly dereference another list of blocktypes.

    Like any engineering problem, the first step is to break it apart: use an intermediate integer, then print it out with Debug.Log(), and see why it is exceeding bounds. And if it isn't then check the x,y,z by printing them out.
     
  3. JohnnysSoftwares

    JohnnysSoftwares

    Joined:
    Mar 16, 2016
    Posts:
    11
    Thanks I will try that.
     
    Kurt-Dekker likes this.
  4. JohnnysSoftwares

    JohnnysSoftwares

    Joined:
    Mar 16, 2016
    Posts:
    11
    Okay
    So I used Debug.Log and it said 515 but since I was trying to make it a byte the code would work. This is because bytes can only store up to 255 right? Or am I way off subject?
     
  5. Kurt-Dekker

    Kurt-Dekker

    Joined:
    Mar 16, 2013
    Posts:
    38,520
    Bytes do indeed only store 0 to 255... not sure how you are seeing 515... what exactly are you printing, the contents of the
    voxelMap[,,]
    array at that point?
     
  6. JohnnysSoftwares

    JohnnysSoftwares

    Joined:
    Mar 16, 2016
    Posts:
    11
    I
    Just realized where I messed up on the Debug Log the reason it said 515 is because there wasn't a space between the two separate values. I was printing the VoxelData.ChunkWidth and VoxelData.ChunkHeight.

    So the command read:
    Debug.Log("Checking: " + VoxelData.ChunkWidth + VoxelData.ChunkHeight);

    So what it meant to say was 5 15
     
  7. Kurt-Dekker

    Kurt-Dekker

    Joined:
    Mar 16, 2013
    Posts:
    38,520
    Whew, I was starting to suspect you were using some new-fangled byte that had like 10 or more bits. :) I was gonna ask you where you got those! They sound useful...

    Seriously, just stick a
    + "," +
    in there and off you go.

    Also, don't bother printing those two values, they're marked as readonly and hence constants. It's the resulting dereferenced value you want, what you use to look up the chunk type or whatever it was called. Or the x,y,z values... those are where the bad value is.
     
  8. JohnnysSoftwares

    JohnnysSoftwares

    Joined:
    Mar 16, 2016
    Posts:
    11
    Lol
    So I fixed the command and now the console says "Checking: 5,15".
     
  9. Kurt-Dekker

    Kurt-Dekker

    Joined:
    Mar 16, 2013
    Posts:
    38,520
    As my post noted above, those values are constants. There's no point in printing them out. It's like asking what time the 6pm train departs.

    Print out values that contain actual data, such as x,y,z and also voxelMap[x,y,z]

    That's when you're gonna learn some really interesting stuff.
     
  10. JohnnysSoftwares

    JohnnysSoftwares

    Joined:
    Mar 16, 2016
    Posts:
    11
    So I think I did this correctly, I am not sure but here goes I typed:
    Debug.Log("Checking: " + voxelMap[x, y, z]);

    And it x, y, z does not exist in the current context. Sorry I am pretty new to Unity.
     
  11. Kurt-Dekker

    Kurt-Dekker

    Joined:
    Mar 16, 2013
    Posts:
    38,520
    Is the error happening in line 59 of the script as numbered above? Because if it is, that context certainly exists.

    If it is not, just print out EVERY value immediately before the line where the error happened. This is basic debugging steps.
     
  12. JohnnysSoftwares

    JohnnysSoftwares

    Joined:
    Mar 16, 2016
    Posts:
    11
    So I put the code before the line with the error. And I got some new errors. 9 to be exact.

    Invalid token '('
    Type Expected
    Tuple must contain at least two elements
    ) expected
    Invalid token "Checking: " in class...
    Array size cannot be specified in a variable declaration occured 3 times
    Invalid token ')'
     
  13. JohnnysSoftwares

    JohnnysSoftwares

    Joined:
    Mar 16, 2016
    Posts:
    11
    My bad
    I put it in wrong spot, now it says Checking 0
    Checking 1
     
  14. Prasenkakade

    Prasenkakade

    Joined:
    Mar 30, 2020
    Posts:
    1
    I am having the same problem with the same code
    please help
     
  15. reekjohns

    reekjohns

    Joined:
    Jul 29, 2020
    Posts:
    1
    This exception means that you're trying to access a collection item by index, using an invalid index. An index is invalid when it's lower than the collection's lower bound or greater than or equal to the number of elements it contains. Indexing an empty list will always throw an exception. Use a method like Add to append the item to the end of the list, or Insert to place the item in the middle of the list somewhere, etc. You cannot index into a list if that offset doesn't exist. IndexOutOfRangeException exception is thrown as a result of developer error. Instead of handling the exception, you should diagnose the cause of the error and correct your code.
     
  16. Rafayboss01

    Rafayboss01

    Joined:
    May 10, 2020
    Posts:
    12
    did anybody find a fix to this
     
  17. Bi1cool

    Bi1cool

    Joined:
    Sep 27, 2020
    Posts:
    1
    Finish the episode 4 (the next one) and you will not have the error any more. Me it's that I do and it's work.