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.
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.
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.
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.
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.
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?
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;
}