- Home /
How to Save an multidimensional array trough editor script
How can i save my position plus value in a array trough a editor script. Currently when i click play it resets the values.
At the moment when i click a button in the scene, it will change the value in the array to one, example: buildgrid[1,5] = 1
When it is 1 it will turn to red and you cant build. But when i play it will reset all values back to 0
Below you the grid class and the editor script.
public class Grid : MonoBehaviour
{
public int[,] buildGrid = new int[15,15];
..
..
..
Here is the editor script:
public void OnSceneGUI()
{
for (int x = 0; x < myGrid.buildGrid.GetLength(0); x++)
{
for (int z = 0; z < myGrid.buildGrid.GetLength(1); z++)
{
int a = x * 10;
int b = z * 10;
//Handles.RectangleCap(1, new Vector3(a, 10, b), Quaternion.Euler(90, 0, 0), 5f);
if (myGrid.buildGrid[x, z] == 0)
{
Handles.color = Color.green;
}
else if (myGrid.buildGrid[x, z] == 1)
{
Handles.color = Color.red;
}
if (Handles.Button(new Vector3(a, 10, b), Quaternion.Euler(90, 0, 0), 4.9f, 4.9f, Handles.RectangleCap))
{
if (myGrid.buildGrid[x, z] == 0)
{
myGrid.buildGrid[x, z] = 1;
EditorUtility.SetDirty(target);
}
else if (myGrid.buildGrid[x, z] == 1)
{
myGrid.buildGrid[x, z] = 0;
EditorUtility.SetDirty(target);
}
Debug.Log("Pressed button, value changed to: " + myGrid.buildGrid[x, z] + "| Coords Array X: " + x + " z: " + z + "| Coords A: " + a + " B: " + b);
}
}
}
Answer by RudyTheDev · Apr 13, 2015 at 01:04 PM
Short answer: no, you cannot natively save multi-dimensional arrays or lists. By default, Unity saves public fields that it knows how to serialize. In this case, it doesn't know how. Next time it (de)serializes your class, it resets any edits you have made to unserialized fields (even if you would properly dirty them).
That said, this is how you can do it and I would do it in a properly encapsulated fashion:
using System;
using UnityEngine;
[Serializable]
public class MultiIntArray
{
[SerializeField]
private int width;
[SerializeField]
private int height;
[SerializeField]
private int[] values;
public int Width { get { return width; } }
public int Height { get { return height; } }
public int this[int x, int y]
{
get { return values[y * width + x]; }
set { values[y * width + x] = value; }
}
public MultiIntArray(int width, int height)
{
this.width = width;
this.height = height;
values = new int[width * height];
}
}
Then your code is like:
using UnityEngine;
public class MultiIntArrayTest : MonoBehaviour
{
public MultiIntArray testArray = new MultiIntArray(10, 5);
void Start()
{
testArray[6, 2] = 100;
testArray[0, 0] = 200;
testArray[0, 4] = 300;
testArray[9, 0] = 400;
testArray[9, 4] = 500;
}
}
It won't look pretty in the editor inspector without a good PropertyDrawer and I'm entirely too lazy to do that now.
But than i still have to do everything myself:
void Start()
{
testArray[6, 2] = 100;
testArray[0, 0] = 200;
testArray[0, 4] = 300;
testArray[9, 0] = 400;
testArray[9, 4] = 500;
}
I need to make it clickable in the editor window
I thought you were doing OnSceneGUI
and working on myGrid.buildGrid
there. So you would just use buildGrid
as:
public $$anonymous$$ultiIntArray buildGrid = new $$anonymous$$ultiIntArray(15, 15);
(and .GetLength(0/1)
would be .Width
and .Height
)
That code would work with this version the same way. That Start
is just an example.
This is just an example of how you would handle such cases in Unity. The exact classes and usage are up to you.
If you need to modify the values in inspector, then you need to write an Editor
script or PropertyDrawer
to handle it.