(Solved) How to assign multiple actions to an int array?

Hi all,
Please help a noob out.
I’ve made a 2d int Array and made a visual representation of it in the Inspector. I’ve used this tutorial:

Now I want every int to represent a cube.

  • The number I assign in the Inspector to the array element is the color of the cube.
  • The position in the row is the x coordinate of the cube.
  • The -row is the y coordinate of the cube.

How do I make this possible?

The X and Y coordinate should be easy enough to do, just take the row index as the Y axis position and column index as the X axis, or the reverse if it doesnt work. Multiply the index number by the side length of the cube.

I did not watch the entire video, but if you are able to assign any type as an element in the 2D array, then make it a 2D Color array instead of ints. Assuming you are generating the cubes, you’d then assign the color to the cube when you create the cube.

Thank you for your reply.
I didn’t explain it well enough. I’ve made it an int Array so I could easily change the Object I want to see. For now there simple colored cubes but once the game works I want to change the cubes for some better looking Objects.
So now I have the int Array (Board) in the Inspector and a GameObject Array (Cubes) with the different Cubes. I would like, if I change an int in the Board it will use the corresponding element from the Cubes Array.

public int[][] board;
public GameObject[] cubes;
.
.
.
for(int y = 0; y < board.length; y++){
    for(int x = 0; x < board[y].length; x++){
        GameObject obj = cubes[board[y][x]];
        Vector3 pos = new Vector3(x, 0, y);
        Instantiate(obj, pos, Quaternion.identity);
    }
}

Thank you very much.

It really sucks to be a noob and don’t understand how to code yet. I watch a lot of tutorials and try a lot but I can’t find the logic to adapt code to my specific situation. I learn every day and I know to keep trying. So here are the three scripts which I have and try to make work.

Script 1 (made by the creator of the tutorial mentioned above and adapted by me) This script is in the Editor folder.

using UnityEngine;
using UnityEditor;
using System.Collections;

[CustomPropertyDrawer(typeof(ArrayLayout))]
public class CustPropertyDrawer : PropertyDrawer
{
    public override void OnGUI(Rect position,SerializedProperty property,GUIContent label)
    {
        EditorGUI.PrefixLabel(position,label);
        Rect newposition = position;
        newposition.y += 18;
        SerializedProperty data = property.FindPropertyRelative("rows");

        //data.rows[0][]
        for(int j=0;j<9;j++)
        {
            SerializedProperty row = data.GetArrayElementAtIndex(j).FindPropertyRelative("row");
            newposition.height = 18;
            if(row.arraySize != 9)
                row.arraySize = 9;
          
            newposition.width = 18;
            for(int i=0;i<9;i++)
            {
                EditorGUI.PropertyField(newposition,row.GetArrayElementAtIndex(i),GUIContent.none);
                newposition.x += newposition.width;
            }

            newposition.x = position.x;
            newposition.y += 18;
        }
    }

    public override float GetPropertyHeight(SerializedProperty property,GUIContent label)
    {
        return 18 * 10;
    }
}

Script 2 (Also made by the creator of the tutorial and adapted by me)

using UnityEngine;
using System.Collections;

[System.Serializable]
public class ArrayLayout
{
    [System.Serializable]
    public struct rowData
    {
        public int[] row;
    }

    public rowData[] rows = new rowData[9];
}

Script 3 (I combined a script from the tutorial with the code from Laperen) This script is on an empty Game Object.

using UnityEngine;
using System.Collections;

public class Board : MonoBehaviour
{
    public ArrayLayout[][] board; // This makes the 9x9 appear in the Inspector.
    public GameObject[] cubes;

    void Start ()
    {
        for(int y = 0; y < board.Length; y++)
        {
            for(int x = 0; x < board[y].Length; x++)
            {
                GameObject obj = cubes[board[y][x]];
                Vector3 pos = new Vector3(x, y, 0);
                Instantiate(obj, pos, Quaternion.identity);
            }
        }
    }
}

I get two errors:
NullReferenceException: Object reference not set to an instance of an object Board.Start () (at Assets/Scripts/Board.cs:22)

and

Assets/Scripts/Board.cs(15,56): error CS0029: Cannot implicitly convert type ArrayLayout' to int’

So I know there are some mistakes. What am I doing wrong and how can I fix it so it works as I want?

I don’t know about the first error, since your Board script only holds 21 lines of code, and it’s complaining at line 22. Did you include the full script, or change anything when you entered it?

The second one, you’re trying to access an int from an arraylayout, which are entirely different types. Do you store the real int that you want inside the rowData variable, or what does that contain? If rowData contains the object type you want, then I think you should change

GameObject obj = cubes[board[y][x]];

into

GameObject obj = cubes[board[y][x].rowData[x]];

Thank you for your reply.

I did enter the full script and it does only have 21 lines.

To be honest, I’m not sure what the rowData is. I think it holds the 9 rows.

When I make the change you suggested I get the first error again and as second error I get:

Assets/Scripts/Board.cs(15,68): error CS0572: rowData': cannot reference a type through an expression; try ArrayLayout.rowData’ instead

When I change it to ArrayLayout.rowData the letters turn red.

Edit: I restarted MonoDeveloper and Unity. The first error message is gone :slight_smile:

Oops, that was my mistake, it should be GameObject obj = cubes[board[y][x].rows[x]];

Edit: No, that’s also wrong. Your structure is very weird. I think you should reconsider what your structure looks like. Now I think it should be more like

GameObject obj = cubes[board[y][x].rows[x].row[x]];

but it’s very messy and looks wrong.

I think it’s better if your ArrayLayout contained the information instead, but that might mess up how you’ve coded so far.

Edit 2:

Consider changing your ArrayLayout like this:

    using UnityEngine;
    using System.Collections;
  
    [System.Serializable]
    public class ArrayLayout
    {
            public int obj;
    }

And change variable to be the same as the block/tile you want. And that way, you can fetch your prefab by using

GameObject obj = cubes[board[y][x].obj];

I just noticed because I placed [ ][ ] inpublic ArrayLayout[][] board; // This makes the 9x9 appear in the Inspector. the array isn’t visible anymore in the inspector. So now I’m completely lost.

If I use your code the errors are gone but I don’t have the display in the inspector anymore because I placed those damned [ ][ ]. But when I remove them your code doesn’t work anymore.

Is this what it’s like to be a coder?
I’ll ask if the creator of the tutorial also comes to this thread.

Well, that was my suggestion, it feels like you have many unnecessary arrays that you don’t need/use. You could keep it as it was, but it’d most likely be wasteful. Since you’ve changed how your array works then it follows that the inspector doesn’t show it correctly. You have to change the OnGUI() method to draw the 2D array with your new setup.

Hello,

This should be the code:

    public ArrayLayout myboard; // This makes the 9x9 appear in the Inspector.
    public GameObject[] cubes;

    void Start ()
    {
        for(int y = 0; y < 9; y++)
        {
            for(int x = 0; x < 9; x++)
            {
                int index = board.rows[y].row[x];
                if(index >0 || index <cubes.Length){
                      GameObject obj = cubes[index];
                      Vector3 pos =new Vector3(x, y,0);
                       Instantiate(obj, pos, Quaternion.identity);
                }
            }
        }
    }

Explanation:
The ‘myboard’ is an object in your ‘Board’ class. ‘myboard’ has an array of ‘rowData’ called as ‘rows’. Every element in this array represents a single row.
So you access this row by:
myboard.rows[y]
where ‘y’ is your row number.

Then every row is, basically, a struct object which has an array of itself for the row. Every element in this array is one individual unit. So you access every element in this as:
myboard.rows[y].row[×]

I have added a condition check for this int to check if it doesn’t fall out of range of your ‘Cubes’ array, because if it does, then it might be giving you a NullPointerException because of that.

Hope this helps.

There’s a small error with the condition that you added on line 12.

There should be an “&&” instead of “||”, otherwise you can still recieve the NullPointerException, and you should include the zero too.

if(index >= 0 && index <cubes.Length){

Thank you both so much!