- 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