When working with two-dimensional arrays, it’s very easy to confuse in the code where the columns are and where the rows are. Moreover, you need to be very careful when dealing with nested for loops when iterating over such arrays, to clearly understand how you are “traversing” this matrix (from left to right, top to bottom, or vice versa).
Of course, when you see such an array in the code editor (as text), everything is obvious - the column goes from top to bottom, the row goes from left to right, and the origin is at the top left. BUT, as soon as you need to transfer this data to the console screen or to 3D/2D space, confusion arises because somewhere the zero coordinates of the screen start from the top left, somewhere from the bottom left. And in 3D, it starts from the middle of the world towards the positive direction along any of the axes. Moreover, the axes can also be different, somewhere the positive Y-axis goes up (as in Unity), and somewhere the positive Z-axis goes up, and so on.
For example, a very common situation is when such an array looks flipped in any direction when output, just like in your case. In such a situation, you need to analyze again in what sequence you output information to the screen or to another space.
I don’t think the code below will help you, but it’s like an example of your idea. There’s a grid, and different shapes above it, and you need to determine which cells these shapes occupy. Right now, it works without launching the game, directly in the editor. You can adjust the number of cells on the grid:
And when moving, the occupied cells turn green, and a two-dimensional array of this grid is additionally displayed in the Game window as zeros and ones.
Here is a lot of unnecessary code aimed solely at visualization. The main logic is located within the Update function.
Code
using System.Linq;
using UnityEngine;
[ExecuteAlways]
public class ArrayGridField : MonoBehaviour
{
[Min(2)]
public int GridSizeX = 10;
[Min(2)]
public int GridSizeZ = 8;
public Transform[] Figures;
public int[,] _grid;
private void OnValidate()
{
_grid = new int[GridSizeZ, GridSizeX];
}
private void OnDrawGizmos()
{
float halfCell = 0.5f;
Vector3 cellSize = new Vector3(0.9f, 0.1f, 0.9f);
for (int z = 0; z < GridSizeZ; z++)
{
for (int x = 0; x < GridSizeX; x++)
{
Vector3 cellCelnter = new Vector3(x + halfCell, 0, z + halfCell);
if (_grid[z, x] == 1)
{
Gizmos.color = Color.green;
Gizmos.DrawCube(cellCelnter, cellSize);
}
else
{
Gizmos.color = Color.white;
Gizmos.DrawCube(cellCelnter, cellSize);
}
//UnityEditor.Handles.Label(cellCelnter, _grid[z, x].ToString());
}
}
}
private void Update()
{
var changedFigures = Figures.Where(i => i.hasChanged);
if (changedFigures.Count() != 0)
{
ResetGrid();
foreach (var figure in changedFigures)
{
foreach (Transform box in figure)
{
int x = Mathf.FloorToInt(box.position.x);
int z = Mathf.FloorToInt(box.position.z);
if (PositionIsValid(x, z))
{
_grid[z, x] = 1;
}
}
}
}
}
private void ResetGrid()
{
for (int z = 0; z < GridSizeZ; z++)
{
for (int x = 0; x < GridSizeX; x++)
{
_grid[z, x] = 0;
}
}
}
private void OnGUI()
{
Rect rect = new Rect(10, (GridSizeZ * 20), 20, 20);
for (int z = 0; z < GridSizeZ; z++)
{
for (int x = 0; x < GridSizeX; x++)
{
GUI.color = _grid[z, x] == 1 ? Color.yellow : Color.black;
GUI.Label(rect, _grid[z, x].ToString());
rect.x += 20;
}
rect.x = 10;
rect.y -= 20;
}
}
private bool PositionIsValid(float x, float z)
{
return x >= 0 && x < GridSizeX && z >= 0 && z < GridSizeZ;
}
}
Just in case, I’ll provide the package so you can immediately “try out” the example.
9724675–1390363–GridExample.unitypackage (17.6 KB)