Array Index out of range

Hello,

I declared an array with a fixed size of 4, but when I try to change the value I get an index out of range error, really not sure why.

I get the error at this line
map_start_x[1] = ((float)map_tiles_width * 10) + map_start_x[0];

Any suggestions?

using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class World : MonoBehaviour
{
    public bool show_debug = false;
    public bool[] regenerate_world = { false, false, false, false };
    public GameObject[] maps;
    public int map_tiles_width;
    public int map_tiles_height;
    public float[] map_start_x = new float[4];
    public float[] map_start_z = new float[4];

    void Start()
    {
        MapPlacementCoordinates();
    }
    private void MapPlacementCoordinates()
    {
        map_start_x[0] = 0f;
        map_start_z[0] = 0f;
        map_start_x[1] = ((float)map_tiles_width * 10) + map_start_x[0];
        map_start_z[1] = map_start_z[0];
        map_start_x[2] = map_start_x[0];
        map_start_z[2] = ((float)map_tiles_height * 10) + map_start_x[0];
        map_start_x[3] = ((float)map_tiles_width * 10) + map_start_x[0];
        map_start_z[3] = ((float)map_tiles_height * 10) + map_start_x[0];
        maps[0].transform.position = new Vector3(map_start_x[0], 0f, map_start_z[0]);
        maps[1].transform.position = new Vector3(map_start_x[1], 0f, map_start_z[1]);
        maps[2].transform.position = new Vector3(map_start_x[2], 0f, map_start_z[2]);
        maps[3].transform.position = new Vector3(map_start_x[3], 0f, map_start_z[3]);

    }
}

Since it’s a public float[ ], on a MonoBehaviour, have you done anything in the Inspector to that array? Did you maybe create your World object instance with those members, and then add the initializer code? If so, the Scene may have saved your World with nulls or shorter arrays instead of getting the benefit of those initializers.

I would suggest you do the allocation of the array in Awake instead of relying on the member initializers, or since it all seems to be useful in the function, do it there.

1 Like

Yes, this would be the first place to look. Here’s why:

Serialized properties in Unity are initialized as a cascade of possible values, each subsequent value (if present) overwriting the previous value:

  • what the class constructor makes (either default(T) or else field initializers, eg “what’s in your code”)

  • what is saved with the prefab

  • what is saved with the prefab override(s)/variant(s)

  • what is saved in the scene and not applied to the prefab

  • what is changed in Awake(), Start(), or even later etc.

Make sure you only initialize things at ONE of the above levels, or if necessary, at levels that you specifically understand in your use case. Otherwise errors will seem very mysterious.

Here’s the official discussion: https://blog.unity.com/technology/serialization-in-unity

Field initializers versus using Reset() function and Unity serialization:

https://discussions.unity.com/t/829681/2

https://discussions.unity.com/t/846251/8

1 Like