Show int[,] Multidimensional Array in Custom Editor Field.

I’m trying to see and edit a 2D Array in a Custom Editor Script Field.
I use a multidimensional array with a 40x40 length. I’m using this Array to store the state of the world and control the player’s movements.
On a single scene there are different maps next to each other to make a route, each of them is made by 40x40 tiles.
I would like to set in the inspector of these maps a different multidimensional Array, so when the player change map, the Array assume the new values by taking them directly from the inspector.
Something like this:


A big field where to insert a big array like:
{{00,00,00,00,01,00,00,00,00},
{00,00,00,00,01,00,00,00,00},
{00,00,00,00,01,00,00,00,00},
{00,00,00,00,01,01,00,00,00},
{00,00,00,01,01,01,00,00,00}} etc.
I’m having tons of troubles to show a simplce 2DArray in the inspector. How can I solve?

So you just want a way to visually show the format of the map in an easy to copy & paste format.

Why not have 2 buttons instead: Copy To Clipboard, Paste From Clipboard.

Now when copy from clipboard is clicked you place the array into the clipboard. You could format it into a serialized string if you want… if it’s really just an int array though, Windows clipboard should be able to support it directly.

When Paste is clicked, pull the object from the clipboard, validate its legit (that it meets the format you chose to transport it as). And if it does, update the state of your script with it.

Here you can find an article about reading/writing to the windows clipboard:

I dont think unity serializes multidimensional arrays (int[,])
We can use a trick to get unity to serialize a jagged array though (int[ ][ ])
Maybe this will be enough for you?

Example code.
Click for Code

Our Class Code

using UnityEngine;

public class SomeClass : MonoBehaviour
{
    public ArrayInt[] mArray;

    void Start()
    {
        Debug.Log(mArray[mArray.Length - 1][mArray[mArray.Length - 1].Length - 1]); //debugs the last value
    }
}

Serializable Multidimensional Array Helper Code

using System;

public class Array<T>
{
    public T[] values;

    public Array(int size)
    {
        values = new T[size];
    }

    public int Length {get {return values.Length;}}

    public T this[int index]
    {
        get{return values[index];}
        set{values[index] = value;}
    }
}

[Serializable]
public class ArrayInt : Array<int>
{
    public ArrayInt(int size) : base(size){}
}

Custom Inspector Code

using UnityEngine;
using UnityEditor;

[CustomEditor(typeof(SomeClass))]
public class SomeClassInspector : Editor
{
    int firstDimensionSize;
    int secondDimensionSize;
    string confirmation;
    bool editMode;

    public override void OnInspectorGUI()
    {
        DrawDefaultInspector();
        SomeClass someClass = (SomeClass)target;

        if(CanCreateNewArray()) CreateNewArray(someClass);

        SetupArray(someClass);
    }

    bool CanCreateNewArray()
    {
        EditorGUILayout.BeginHorizontal();
        if(GUILayout.Button("Create New Array")) editMode = true;
        if(GUILayout.Button("Cancel")) editMode = false;
        EditorGUILayout.EndHorizontal();

        return editMode;
    }

    void CreateNewArray(SomeClass someClass)
    {
        GetDimensions();
        if(ConfirmedCanCreate()) CreateArray(someClass);
    }

    void GetDimensions()
    {
        firstDimensionSize = EditorGUILayout.IntField("First Dimension Size", firstDimensionSize);
        secondDimensionSize = EditorGUILayout.IntField("Second Dimension Size", secondDimensionSize);
    }

    bool ConfirmedCanCreate()
    {
        EditorGUILayout.BeginHorizontal();
        EditorGUILayout.LabelField("Type YES and press Create to create new array. This will clear your old array!!", EditorStyles.wordWrappedLabel);
        confirmation = EditorGUILayout.TextField(confirmation);
        EditorGUILayout.EndHorizontal();

        EditorGUILayout.BeginHorizontal();
        bool canCreate = (GUILayout.Button("Create New Multidimensional Array") && confirmation == "YES");
        EditorGUILayout.EndHorizontal();

        if(canCreate)
        {
            confirmation = "";
            editMode = false;
            return true;
        }
        return false;
    }

    void CreateArray(SomeClass someClass)
    {
        someClass.mArray = new ArrayInt[firstDimensionSize];
        for(int i = 0; i < firstDimensionSize; i++)
        {
            someClass.mArray[i] = new ArrayInt(secondDimensionSize);
        }
    }

    void SetupArray(SomeClass someClass)
    {
        if(someClass.mArray != null && someClass.mArray.Length > 0)
        {
            for(int i = 0; i < someClass.mArray.Length; i++)
            {
                EditorGUILayout.BeginHorizontal();

                for(int j = 0; j < someClass.mArray[i].Length; j++)
                {
                    someClass.mArray[i][j] = EditorGUILayout.IntField(someClass.mArray[i][j], GUILayout.Width(20));
                }

                EditorGUILayout.EndHorizontal();
            }
        }
    }
}

Maybe this can get you started.
It looks like this
Click for Image

2302350--155024--Inspector.png

Yeah, the second way works, maybe it shows the Array in the inspector but the problem is that I’m working with an 40x40 array. I don’t think It would be easy to me to fill 1600 boxes. I use an automatic generator to build the array. I just need a way to paste this array in a field.
Thinking about lordofduct’s answer: If i paste the array in the Clipboard of the different inspectors, I’ll be able to change these values in game? When the player step from a map to another, I need the array to change it’s values with the values he find in the clipboard of the current map. Otherwise the player will walk everywhere without control.

Lately I thought of a solution.
Instead of showing a Field to insert the Array. I’ll use a TextField. In this way I can insert the entire Array in the field and then split the string to get my int[,] Array.
But I need help with this … I Looked for some answers or threads but I found little and very inaccurate .