Variables lost when updating script!

Hi

In my script (C#) I use editor scripts to generate a 2d array (200*200) of type MyClass (for example).
Although when I change something in the script and then compile it, the array is lost, it just returns null, I want it to stay calculated.

Can someone help?

Can we see a code example please.

In what scope is the array declared?

I think you have to use EditorUtility.SetDirty to inform Unity that your script has changed the public variables of your class. The Unity editor does this automatically.

Quite interesting, I never noticed the setDirty method. What does Unity exactly do then? Save the public vars and reapply them after the recompilation is done?

I’m not sure exactly what is going on inside Unity, but it must be saving the values of instance variables and restoring them as necessary (the GameObjects are ultimately just normal Mono objects) . The Unity editor can always detect when something has been intentionally changed, but it wouldn’t know what needed to be saved after a script has run. SetDirty lets you state explicitly what should be saved.

Nope, not working. Tried with the SetDirty function but it still wont save.
Can’t show you all my code since it is to long, here’s a simplification.

This is the editor code

if (GUILayout.Button ("Scan Map")) {
	((AstarPath)target).Scan ();
	EditorUtility.SetDirty (target);
}

And this is the Scan () function

Node[][,] nodes = new Node[levels][,];//The Lost Array
		
for (int i=0;i<levels;i++) {//Depth
	nodes[i] = new Node [worldWidth,worldWidth];
}

for (int y=0;y<levels;y++) {//Height
	for (int z=0;z<worldWidth;z++) {//Depth
		for (int x=0;x<worldWidth;x++) {//Width
			//Calculate the position of the node
			Node node = nodes[y][x,z] = new Node ();
		}
	}
}
staticNodes = nodes;//Static Nodes is a public variable in the script, it's actually that variable which is lost.

This code is also executed when the game starts.

Maybe Unity only checks for data types that can be displayed/changed in the editor. A 2D array isn’t one of the types you can normally see in the editor, so it’s possible that it doesn’t get saved.

EditorUtility.SetDirty() is for reminding the editor to save changes to disk (in your Assets folder), not in instances of scripts across compiles. It won’t have any effect in this situation.

Unfortunately, don’t think there is a way to keep things that the inspector doesn’t show across compiles. If there were, testing would be a lot more convenient.

As it stands, you’ll need to store your data in one-dimensional arrays, or have your script re-build it if it finds the array null all of a sudden.

:frowning:
But one-dimensional arrays doesn’t show up in C# either, do they?

Isn’t there something like System.Serializeable you can tag the variable with?

One-dimensional arrays will show up, if their element type is something that the inspector can already show. This includes classes that inherit from System.Object and are tagged with System.Serializable.

Ok, but if I use a custom inspector, will the array be saved then?

As far as I know, anything that would be saved without a custom inspector will be saved with one.

Great, will try it :smile:

Hmm, the array seams to big for Unity, it just crashes.

I’m using an array of length 10 000. Each element has:
16-24 Ints (depending on the length of some arrays)
37 Floats
2 Bools
5-14 References

Is this to large?

Yeah that’s pretty big. You might consider saving to a file, and re-loading your representation in memory whenever it goes null.

I’m a bit lost here, but I do know if you try and do a standard XML serialize on a C# class that contains a multi-dimensional array it will throw an exception.

Hi

I tried with XMLTextWriter, with my 10 000 objects it resulted in a 1.7 mb xml file.
That’s way to large for my project, does anyone know how to write to a file which takes up smaller space?

Well, from my calculations, your object type uses somewhere around 250-300 bytes, depending on the configuration. 250 * 10000 = 2500000, if I’m not mistaken, so a 1.7MB file seems pretty good. You’d certainly reduce the size of the file if you used a binary file format or you could use something like SharpZipLib to compress the XML file before writing.

You might be able to code yourself a bit of a reduction in memory if you go for a binary format. Do the integers need the full range of the int type, or could you reduce them to bytes? Similarly, if the floats have a small range and only need limited accuracy, you could replace them with bytes or short integers. You might be able to put the bools into unused bits of one or more of the other fields. For the references, how many objects need to be referenced? If there are only a few, you could maybe refer to them via entries in a lookup table.

If you need some more concrete suggestions, perhaps you could give a bit more detail about what the data represents?

Hi

All the references are references to another object in the array, so I can replace them with two ints.

This is what I need to save

public class Node {
	//Global position of the node
	public Vector3 vectorPos;
	
	//Local position of the node
	public Int3 pos;//3 ints
	
	public bool walkable = true;
	
	public float[] angles = new float[9];//Floats with range from 0-1 representing angles from 0-90, at most it needs an accuracy of 1/90 or 1/45
	public Node[] neighbours;//Reference to other nodes in the array
	
	public int[] neighboursKeys;//Ints with range from 0-8
	
	public int area = 0;
}