Custom editor issue - Index out of bound

I am having the same error over and over after recreating this tutorial my own way.

I tried to create a custom editor for my script to spawn random objects. I keep having this error from the custom editor script when the size of my 3 arrays are over 1:

Retieving array element that was out of bounds UnityEditor.SerializedProperty:GetAwwayElementAtIndex(int32)
NullReferenceException:Object references not set to an instance of an object
UnityEditor.PropertyHandler.OnGuiLayout (UnityEditor.SerializedProperty property, UnityEngine.GUIContent label, system.boolean includeChildren, UnityEngine.GUILayoutOption[ ] …)

Here is how I Initialize my arrays in the reference script for the editor :

Public class SpawnObjectsOnTerrain : MonoBehaviour
{
public Terrain WorldTerrain;
public LayerMask TerrainLayer;
public static float TerrainLeft, TerrainRight, TerrainTop, TerrainBottom, TerrainWidth, TerrainLength, TerrainHeight;

public static ArrayList units = new ArrayList();
public static ArrayList positions = new ArrayList();
public static ArrayList rotations = new ArrayList();

public GameObject[ ] SpawnObjects = new GameObject[QtItemToSpawn]; //in custom editor script
public int[ ] AmountOfObjects = new int[QtItemToSpawn];//in custom editor script
public float[ ] AddedHeight = new float[QtItemToSpawn];//in custom editor script
public const int QtItemToSpawn = 1;

[...]

and here is the full CustomEditorScript:

using UnityEngine;
using UnityEditor;

[CustomEditor(typeof(SpawnObjectsOnTerrain))]
public class SpawnObjectsOnTerrainEditor : Editor
{
    private bool[] showObjectsSlots = new bool[SpawnObjectsOnTerrain.QtItemToSpawn];
    private SerializedProperty SpawnObjectProperty;
    private SerializedProperty AmountOfObjectProperty;
    private SerializedProperty ObjectHeightProperty;
    private const string WorldPropObjectToSpawnName = "SpawnObjects";
    private const string WorldPropObjectAmountName = "AmountOfObjects";
    private const string WorldPropObjectHeightName = "AddedHeight";


    private void OnEnable()
    {
        SpawnObjectProperty = serializedObject.FindProperty(WorldPropObjectToSpawnName);
        AmountOfObjectProperty = serializedObject.FindProperty(WorldPropObjectAmountName);
        ObjectHeightProperty = serializedObject.FindProperty(WorldPropObjectHeightName);
    }

    public override void OnInspectorGUI()
    {
        serializedObject.Update();
        for (int i=0;i < SpawnObjectsOnTerrain.QtItemToSpawn;i++)
        {
            SpawnObjectGUI(i);
        }

        serializedObject.ApplyModifiedProperties();
    }

    private void SpawnObjectGUI(int index)
    {
        EditorGUILayout.BeginVertical(GUI.skin.box);
        EditorGUI.indentLevel++;

        showObjectsSlots[index] = EditorGUILayout.Foldout(showObjectsSlots[index], "Object slot:" + (index.ToString()));

        if (showObjectsSlots[index])
        {
            EditorGUILayout.PropertyField(SpawnObjectProperty.GetArrayElementAtIndex(index), new GUIContent("SetObject:" + index.ToString()));
            EditorGUILayout.PropertyField(AmountOfObjectProperty.GetArrayElementAtIndex(index), new GUIContent("SetAmount:" + index.ToString()));
            EditorGUILayout.PropertyField(ObjectHeightProperty.GetArrayElementAtIndex(index), new GUIContent("SetHeight:" + index.ToString()));
        }

        EditorGUI.indentLevel--;
        EditorGUILayout.EndVertical();
    }

Please Help ! It bothers me not to understand where the problem is coming from. I feel it’s the use of 3 arrays.

Before the specific line giving you an issue (find it in the console), use Debug.Log() to output two things:

  1. the .Length property of the array
  2. the value you’re trying to dereference it with

You will discover that the value is either below zero, or above Length-1.

Keep in mind arrays are zero-based: a three-element array will have elements 0, 1 and 2

Is there a particular reason why you use a const field to set the size of the arrays? It looks very error-prone to me and I bet that it is the reason that you get those exceptions.

You could create a custom class to bundle your different arrays into one element:

[System.Serializable]
public class SpawnConfiguration {
    public GameObject prefab;
    public int Amount;
    public float Height;
}

Then, use in your SpawnObjectsOnTerrain a List<SpawnConfiguration> spawnConfiguration instead of different arrays.

In your editor, then replace the loop with:

for (int i=0;i < serializedObject.FindProperty("spawnConfiguration").arraySize;i++)
        {
            SpawnObjectGUI(i);
        }

In your SpawnObjectGUI(), you can access the properties of an array element using SerializedProperty.FindPropertyRelative. There are some threads here on the forum that show how it is used.

Adding to what Kurt said, obviously the error you’re getting comes from the fact that you’re asking for an array element with an index that is bigger than the amount of elements you have. So the problem comes form something like “showObjectsSlots[index]” where you call for an object of the list using an index.
When you get one error that doesn’t point directly to anything, you must open the error in the console and you’ll see how the sequence of calls was (Unity now highlights the methods that were called). Just go to the last one (the one that’s closer to the top) and open it. Anything you see next of the form list[index] is probably the suspect

1 Like

I use a const because i followed the tutorial of unity! I solved the problem. Cant really explain why now it works! Thanks for your help! Debugging helped a lot’

1 Like