Jagged arrays become null when I hit Play

Hello =)

So it seems if I have a script that executes in edit mode, and this script has a 2D array, that is built in editor mode, when I click “Play” … this array becomes null.

Is there a way that this jagged array persists when application starts playing?

Or should I not use jagged arrays this way? :-\

Below the test script:

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

[ExecuteInEditMode]

public class Temp : MonoBehaviour {

    public Bounds[][] myJaggedArray;

    public bool setArray;

    public bool debugNow;

    // Use this for initialization
    void Start () {
     
    }
 
    // Update is called once per frame
    void Update () {
        if (setArray) {
            myJaggedArray = new Bounds[2][];
            myJaggedArray [0] = new Bounds[3];
            myJaggedArray [1] = new Bounds[4];

            setArray = false;
        }
 
        if (debugNow) {
            Debug.Log (myJaggedArray.Length);
            Debug.Log (myJaggedArray [0].Length);
            Debug.Log (myJaggedArray [1].Length);
            debugNow = false;
        }
    }

}

Just a quick scan of the code tells me you want this to sort of be a “self initializing” object that takes care of itself in the editor and then can be used in the future with the arrays built out by code in your Update() loop.

If that’s what you want, this construct will not quite get you there.

What you want instead is something like a ScriptableObject, which actually will allow you to create an on-disk instance (just one of them, or many of them, which is where the persistence takes place), and if you need some custom values set up in it, you make a custom editor script for that particular flavor of ScriptableObject, and do your initializations in that editor’s methods.

But all this is predicated on my assumptions of what you’re trying to do, so take it with a grain of salt.

Cool. I’m not very familiar with it, I’ll look into it.

What I’d like is the array to behave like variables exposed in inspector.
Like a “normal” 1D array in which you can store some values in editor … and it’s still there at runtime.

But I could also make a class that holds an array. And make an array of that class.

Oooh, that is EXACTLY what you want a ScriptableObject-derived script for. There’s a few tricky bits: you can’t directly serialize a jagged array: you have to put the array in another class and make an array of those classes.

I hadn’t done it in a while so I was curious and my Google-Fu felt strong tonight, so I put it together for you:

using UnityEngine;
using System.Collections;

[CreateAssetMenu]
public class Temp : ScriptableObject
{
    [System.Serializable]
    public class BoundsArray
    {
        public BoundsArray( int size)
        {
            Inside = new Bounds[size];
// note: if Bounds was a class instead of a struct, you'd have
// to new up each individual one in the array above!
        }
        public Bounds[] Inside;
    }

    [SerializeField]
    public BoundsArray[] myJaggedArray;

    void Reset()
    {
        myJaggedArray = new BoundsArray[2];
        myJaggedArray [0] = new BoundsArray (3);
        myJaggedArray [1] = new BoundsArray (4);
    }
}

The decorator at the top (create asset menu) will stick a handy creator function in your asset context menu (right-click menu), which is indispensable when using ScriptableObjects. And with this you can make as many “varieties” of this sort of a thing as you want, naming each one uniquely in your project.

And then if you make a custom inspector for that object, the sky is the limit! Unity is awesome that way.

1 Like

Wow! That is very useful. I’ve gained +25 INT with this :smile:

Thank you!!

1 Like

You will soon be able to wield the JSON scimitar!

1 Like

I’m not that LVL yet!

But SOON =D