- Home /
 
Array index is out of range
So, I'm trying to create an automated "Face Creator" for my Mesh, so I can just call a function, to create a face in a specific position, and height/width.
Altho, I'm getting a Out of range, array index error: IndexOutOfRangeException: Array index is out of range. RoomCreator.CreateFace (Vector3 position, Int32 width, Int32 height) (at Assets/Scripts/BuildingToolsDeveloper/RoomCreator.cs:42) RoomCreator.CreateMesh () (at Assets/Scripts/BuildingToolsDeveloper/RoomCreator.cs:30) RoomCreator.CreateRoom () (at Assets/Scripts/BuildingToolsDeveloper/RoomCreator.cs:23) RoomCreator.Start () (at Assets/Scripts/BuildingToolsDeveloper/RoomCreator.cs:19)
Line 42, is the "CreateFace" function.
Code:
 using UnityEngine;
 using System.Collections;
 
 public class RoomCreator : MonoBehaviour {
 
     private Vector3[] Mesh_Vertices;
     private Vector2[] Mesh_Uvs;
     private int[] Mesh_Triangles;
 
     private MeshFilter meshFilter;
     
 
     void Start() {
         Mesh_Vertices = new Vector3[100];
         Mesh_Uvs = new Vector2[100];
         Mesh_Triangles = new int[3 * 33];
         meshFilter = GetComponent<MeshFilter>();
 
         CreateRoom();
     }
 
     private void CreateRoom() {
         meshFilter.mesh = CreateMesh();
     }
 
     private Mesh CreateMesh() {
         Mesh m = new Mesh();
         m.name = gameObject.name + "_Mesh";
 
         CreateFace(new Vector3(0,0,0), 1,1);
         CreateFace(new Vector3(0,1,0), 1,1);
 
         m.vertices = Mesh_Vertices;
         m.triangles = Mesh_Triangles;
         m.uv = Mesh_Uvs;
         m.RecalculateNormals();
 
         return m;
     }
 
     private void CreateFace(Vector3 position,int width, int height) { //Line 41. 42 is under this line.
             Mesh_Vertices[Mesh_Vertices.Length] = new Vector3(position.x, position.y, 0);
             Mesh_Vertices[Mesh_Vertices.Length] = new Vector3(position.x + width, position.y, 0);
             Mesh_Vertices[Mesh_Vertices.Length] = new Vector3(position.x + width, position.y + height, 0);
             Mesh_Vertices[Mesh_Vertices.Length] = new Vector3(position.x, position.y + height, 0);
             
             Mesh_Triangles[Mesh_Triangles.Length] = 0;
             Mesh_Triangles[Mesh_Triangles.Length] = 1;
             Mesh_Triangles[Mesh_Triangles.Length] = 2;
             
             Mesh_Triangles[Mesh_Triangles.Length] = 0;
             Mesh_Triangles[Mesh_Triangles.Length] = 2;
             Mesh_Triangles[Mesh_Triangles.Length] = 3;
             
             Mesh_Uvs[Mesh_Uvs.Length] = new Vector2(0,0);
             Mesh_Uvs[Mesh_Uvs.Length] = new Vector2(0,1);
             Mesh_Uvs[Mesh_Uvs.Length] = new Vector2(1,1);
             Mesh_Uvs[Mesh_Uvs.Length] = new Vector2(1,0);
     }
 
 }
 
              $$anonymous$$esh_Vertices.length = 100;
USE index in 0~99
$$anonymous$$esh_Vertices[$$anonymous$$esh_Vertices.length] meas $$anonymous$$esh_Vertices[100], is Out Of Range
Answer by nesis · Jan 15, 2014 at 04:51 AM
You're accessing beyond the end of the Mesh_Triangles array, a common mistake. Use Mesh_Triangles.Length-1 to get the last element in the Mesh_Triangles array.
For example:
 Mesh_Triangles[Mesh_Triangles.Length-1] = 0
 
               This applies to the other arrays where you're using array.Length instead of array.Length-1.
Further, you'll run into issues with your mesh generation. This is because you're only ever accessing the last element of each array, ins$$anonymous$$d of assigning to a different element as the need arises. Your code would benefit from using Lists for simplicity's sake. Here's what I'd recommend (code is rough, but should compile):
 using UnityEngine;
 using System.Collections;
 using System.Collections.Generic;
 public class RoomCreator : $$anonymous$$onoBehaviour {
 //using Lists since they start off with 0 elements, and 
 //can have as many elements added as you want later on
 private List<Vector3> $$anonymous$$esh_Vertices = new List<Vector3>();
 private List<Vector2> $$anonymous$$esh_Uvs = new List<Vector2>();
 private List<int> $$anonymous$$esh_Triangles = new List<int>();
 
 private $$anonymous$$eshFilter meshFilter;
 
 
 void Start() {
    meshFilter = GetComponent<$$anonymous$$eshFilter>();
 
    CreateRoom();
 }
 
 private void CreateRoom() {
    meshFilter.mesh = Create$$anonymous$$esh();
 }
 
 private $$anonymous$$esh Create$$anonymous$$esh() {
    $$anonymous$$esh m = new $$anonymous$$esh();
    m.name = gameObject.name + "_$$anonymous$$esh";
 
    CreateFace(new Vector3(0,0,0), 1,1);
    CreateFace(new Vector3(0,1,0), 1,1);
 
    //since we're using Lists now, we have to turn 
    //them into arrays, otherwise we'll get errors
    m.vertices = $$anonymous$$esh_Vertices.ToArray();
    m.triangles = $$anonymous$$esh_Triangles.ToArray();
    m.uv = $$anonymous$$esh_Uvs.ToArray();
    m.RecalculateNormals();
 
    return m;
 }
 
 private void CreateFace(Vector3 position,int width, int height) {
      $$anonymous$$esh_Vertices.Add(new Vector3(position.x, position.y, 0));
      $$anonymous$$esh_Vertices.Add(new Vector3(position.x+width, position.y, 0));
      $$anonymous$$esh_Vertices.Add(new Vector3(position.x, position.y+height, 0));
      $$anonymous$$esh_Vertices.Add(new Vector3(position.x+width, position.y+height, 0));
      
      //get faces indices
      int a = $$anonymous$$esh_Vertices.Length-1; //index of last element in $$anonymous$$esh_Vertices... so you know the other 3 vertices are -1, -2, -3 from this
      int b = a-1;
      int c = a-2;
      int d = a-3;
      
      //add the indices 3 at a time to make 2 triangles that will form one face
      //tri 1
      $$anonymous$$esh_Triangles.Add(a);
      $$anonymous$$esh_Triangles.Add(b);
      $$anonymous$$esh_Triangles.Add(d);
      //tri 2
      $$anonymous$$esh_Triangles.Add(d);
      $$anonymous$$esh_Triangles.Add(c);
      $$anonymous$$esh_Triangles.Add(a);
 
      //this UV assignment will need fixing, I'm sure... cant be bothered thinking through it right now ;)
      $$anonymous$$esh_Uvs.Add(new Vector2(0,0));
      $$anonymous$$esh_Uvs.Add(new Vector2(1,0));
      $$anonymous$$esh_Uvs.Add(new Vector2(0,1));
      $$anonymous$$esh_Uvs.Add(new Vector2(1,1));
 }
 
 
                 Answer by hirenkacha · Jan 15, 2014 at 04:25 AM
Array's length is always the last index +1. If you try accessing the last element of an array it should be [Length-1] and NOT [Lenght]. For Eg. For an array 'a' having 10 elements, a.Length = 10;
 a[0] = .. //Length=1
 a[1] = .. //Length=2
 .
 .
 a[9] = .. //Length=10
 a[10] = null //Out of Range
 
               So if you want last element of the array, It should be
 Mesh_Vertices[Mesh_Vertices.Length-1]
 
               For flexible array, ie if you want to add element and don't care about length of it, use List. For that you just have to use
 public List <Vector3> Mesh_Vertices = new List<Vector3>();
 
 private void CreateFace(Vector3 position,int width, int height)
 {  
     Mesh_Vertices.Add(new Vector3(position.x, position.y, 0));
     Mesh_Vertices.Add(new Vector3(position.x+width, position.y, 0));
     Mesh_Vertices.Add(new Vector3(position.x+width, position.y+height, 0));
     Mesh_Vertices.Add(new Vector3(position.x, position.y+height, 0));
 }
 
              Problem is, that it will not.
You see, $$anonymous$$esh_Vertices.Length is 100 from the start, and not actually 0 as the default value. This means, if I do what you wrote above, it will just overwrite the same element/index with new information.
Array index starts from 0 and ends at Length-1 as explained above. Come to this chatroom to explain what you want exactly.
Your answer
 
             Follow this Question
Related Questions
Failed setting triangles in my mesh 1 Answer
Can someone tell me what is wrong with this? 2 Answers
Modify mesh problems 1 Answer