Array initialized in script is coming up as incomplete, in wrong order or just empty?

Im seeing this strange behaviour and cant seem to fix it. I have two arrays that I have initialized in script. Each having 43 elements within them.

This is how I am declaring and initializing them

[SerializeField]
        private int[] missionSequence =
        {
            1, 2, 3, 4, 5, 1, 23, 25, 21, 6, 7,
            8, 25, 4, 9, 10, 11, 12, 13, 14, 15,
            10, 16, 17, 18, 19, 20, 21, 22, 24,
            26, 27, 28, 29, 200, 201, 202,
            203, 204, 205, 206, 208, 209
        };
  

        [SerializeField]
        private string[] sceneNames =
        {
            "Green 1", "Green 2", "Green 3", "Green 4", "Green 5", "Red Defense 1", "Red 23", "Red 25", "Red 21", "Green 6", "Green 7",
            "Green 8", "Red Defense 2", "Red Defense 3", "Green 9", "Green 10", "Green 11", "Green 12", "Green 13", "Green 14",
            "Green 15", "Green Defense 1", "Green 16", "Green 17", "Green 18", "Green 19", "Red 20", "Red 21", "Red 22",
            "Red 24", "Red 26", "Red 27", "Red 28", "Red 29", "Yellow 200", "Yellow 201", "Yellow 202",
            "Yellow 203", "Yellow 204", "Yellow 206", "Yellow 207", "Yellow 208", "Yellow 209"
        };

The problem is that these are not shown in editor. The int[ ] only reads 14 of the 43 elements and anything after that is null, whereas the string array is null from the start.

Debug.Log(sceneNames[0]) gives the error:

This is what the arrays look like in Unity (and when uploading screenshot I also noticed that the elements are in the wrong order)???:

8717781--1178523--image_2023-01-09_214336251.png

I have tried every possible array initialization method mentioned in Arrays - C# reference | Microsoft Learn but I am getting the same problem.

Whats interesting is that if I change the name to missionSequence2, and then save it works and shows all 43 elements, but after a couple minutes or after making any other changes to the script I get the same problem again with the renamed array also.

Is this a known bug? Has anyone else experienced this?

Im using Unity 2021.3.14f1

Reset the component in the upper right corner.

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)

  • 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.

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

1 Like

Thanks a lot Kurt, that was very helpful.

The problem was indeed with the initialization and adding SerializedField to it. I thought the only purpose of SerializedField with private variables was to allow us to view these variables in editor while keeping them private. Today I realized thats not the case.

Wasted so much time debugging this, but atleast learned something new…

1 Like

Are you ready to keep going? :slight_smile:

It feels like each one of your scene / sequence number things should just be an instance of a ScriptableObject-derived script.

Then just load them or drag them in and all the data for each level is in one central object on disk.

Google up some ScriptableObject tutorials. It’s super-simple easy stuff for making rich content without a lot of code that almost anybody on your team can tweak / adjust.

1 Like

Thanks. I’ve always wanted to use scriptable objects, but could not see the benefit over normal C# class.

For example, to hold data for each region in my missionSequence I have the following script

[System.Serializable]
public class Region
{
    //public string name;                 // this is repeated in countryName.. so no point of this..
    public enum theCountries
    {
        PLAYER,
        GREEN,
        RED
    }

    public theCountries countryName;
    public int regionIndex;
    public bool canAttack;                  // this decides whether player can click on this region or not.
   

    [TextArea]
    public string regionDescription;
    [TextArea]
    public string regionObjective;
    [TextArea]
    public string regionHint;
}

Is there a benefit scriptable objects provide over the above?

Thanks :slight_smile:

It lets you make actual individual files for each “thing,” in this case a Region.

You can then drag and drop, mix-and-match etc however you like.

Each one is a file on disk that you can reason about, edit, modify, etc., and nothing in your scene / prefab would have to change. I love 'em.

1 Like