Creating grids with empty cells

Hi everyone,

I have created a 9x9 grid using black UI Images of sizes 33x3 horizontally and 3x33 horizontally nested in 2 loops i and j (i for rows and j for columns) and an array int [ ] Grid.

I create empty cells in the grid, and try to adapt the grid to the empty cells.

Here’s my code:

    void DrawGrid()
    {
        Vector3 startPosition = transform.position;

        float horizontalOffset = Colonnes * cellSize * 0.5f - cellSize * 0.5f;
        float verticalOffset = Lignes * cellSize * 0.5f - cellSize * 0.5f;

        for (int row = 0; row <= Lignes; row++)
        {
            for (int col = 0; col <= Colonnes; col++)
            {
                if ((Grille[row, col] == 0) && (Grille[row, col + 1] == 0))
                {
                    Vector3 position = startPosition + new Vector3(col * cellSize - horizontalOffset, -row * cellSize + verticalOffset);
                    if (col < Colonnes)
                    {
                        CreateLine(verticalLinePrefab, position + new Vector3(cellSize / 2, 0, 0));
                    }
                }

    void CreateLine(Image linePrefab, Vector3 position)
    {
        Image newLine = Instantiate(linePrefab, position, Quaternion.identity);
        newLine.transform.SetParent(transform);
    }
}

The problem is that this doesn’t create a border.
If you have code like :

for (int row = 0; row <= Lignes; row++)
        {
            for (int col = 0; col <= Colonnes; col++)
            {
                if ((Grille[row, col] == 0) && (Grille[row, col + 1] == 0))
                {
                    Vector3 position = startPosition + new Vector3(col * cellSize - horizontalOffset, -row * cellSize + verticalOffset);
                    if (col < Colonnes)
                    {
                        CreateLine(verticalLinePrefab, position + new Vector3(cellSize / 2, 0, 0));
                    }
                }

If you can help me to make the left, right, top, bottom edges taking into account the empty squares.

Your help is welcome,

Thanks,

A+

All you need to do is add 1 more to each row and column, and calculate the iterations by the cell size. That way the first iteration is row * cellSize = 0 , same for col and that would be your border, as the end pieces would be an extra cellSize.

H

Can you give me some code (as in the example below):

for (int row = 0; row <= Lignes; row++)
        {
            for (int col = 0; col <= Colonnes; col++)
            {
                if ((Grille[row, col] == 0) && (Grille[row, col + 1] == 0))
                {
                    Vector3 position = startPosition + new Vector3(col * cellSize - horizontalOffset, -row * cellSize + verticalOffset);
                    if (col < Colonnes)
                    {
                        CreateLine(verticalLinePrefab, position + new Vector3(cellSize / 2, 0, 0));
                    }
                }

J’ai essayé de changer le code:

if ((Grille[row, col] == 0) && (Grille[row, col + 1] == 0))

by changing col + 1 to col - 1, but that doesn’t change anything.

If you have any ideas,

we’d love to hear them,

A+

Most likely your LineRenderers are simply too long. Shorten them by enough to fit within your existing border.

The simplest form I can think:

int rows = 20;
int col = 20;
float cellSize = 0.5f;

for (int i = 0; i < rows + 1; i++)
{
    for (int j = 0; j < col + 1; j++)
    {
        Vector3 placement = new Vector3(i * cellSize, 0, j * cellSize);
        Instantiate(objPrefab, placement, Quaternion.identity);
    }
}

But you’ll obviously need to change the cellSize to fit your needs.

But you add one more to the iteration, as you’ll see i < rows + 1;, since the first will be 0 and the last will be one extra. Since most “cells” use the center for other object placement, if size is “0.5f” then first center would be half that, Vector3(0.25f, 0, 0.25f) for example.

And if you wanted first center cell to be (0,0,0) then add:

int rows = 20;
int col = 20;
float cellSize = 0.5f;
float startPos = -(cellSize / 2); // as negative

for (int i = 0; i < rows + 1; i++)
{
    for (int j = 0; j < col + 1; j++)
    {
        Vector3 placement =
            new Vector3(startPos + i * cellSize, 0, startPos + j * cellSize);
        Instantiate(objPrefab, placement, Quaternion.identity);
    }
}

Hi,

Sorry, but the code you gave me doesn’t give any grids.

If you can review the code with verticalLinePrefab and hoizontalLinePrefab.

Thank you for your help,

A+

the grid is just “i” and “j”

What do you mean by objPrefab?

Wouldn’t it be better to use verticalLinePrefab to draw vertical lines and horizontalLinePrefab for horizontal lines to create a grid with holes in the grid.

A+

it would be FAR better if you actually specified what you’re trying to do.

For instance, you mention UI but you’re using LineRenderers. THOSE ARE NOT COMPATIBLE!

A grid can be made of many different things.

  • lines drawn between the cells

  • boxes for each cell

  • plus marks (+) between the invisible boxes

  • Something else?

  • is it 2D or 3D?

  • 2D objects in a 3D world?

Remember: we cannot read your mind or see your screen.

Generally…

How to report your problem productively in the Unity3D forums:

http://plbm.com/?p=220

This is the bare minimum of information to report:

  • what you want (pictures or sketches may be helpful here)
  • what you tried
  • what you expected to happen
  • what actually happened, log output, variable values, and especially any errors you see
  • links to documentation you used to cross-check your work (CRITICAL!!!)

The purpose of YOU providing links is to make our job easier, while simultaneously showing us that you actually put effort into the process. If you haven’t put effort into finding the documentation, why should we bother putting effort into replying?

J’essaie de créer l’image suivante :

[[ /url]

Comme vous pouvez le voir, il y a des cellules vides (s’il y a 2 cellules vides ou plus les unes à côté des autres, ne tracez pas de ligne ou de colonne entre les 2).

Ma question est simple : comment adapter la grille avec des cellules vides ?

Merci beaucoup,

A+](23/34/99aq.png - Visionneuse Zupimages)

I would just use the Unity Tilemap system for this:

  • chop up all the graphics above into small uniform tiles

  • put those tiles into a Tilemap Grid.

Tilemaps can keep everything aligned for you.

Sorry, but I only have this code (last update):

public class test : MonoBehaviour
{
    public Image horizontalLinePrefab;
    public Image verticalLinePrefab;
    public float cellSize = 1.0f;
    public int numRows = 20;
    public int numCols = 30;
    public int[,] grid; // Assume global.Grille[i,j] is loaded into this grid

    private void Start()
    {
        DrawGrid();
    }

    private void DrawGrid()
    {
        for (int i = 0; i < numRows; i++)
        {
            for (int j = 0; j < numCols; j++)
            {
                if (grid[i, j] != -1)
                {
                    float left = j * cellSize;
                    float right = (j + 1) * cellSize;
                    float top = i * cellSize;
                    float bottom = (i + 1) * cellSize;

                    // Draw left border line if necessary
                    if (j > 0 && grid[i, j - 1] == -1)
                    {
                        DrawLine(horizontalLinePrefab, new Vector3(left, 0, (top + bottom) / 2), new Vector3(left, 0, bottom));
                    }

                    // Draw top border line if necessary
                    if (i > 0 && grid[i - 1, j] == -1)
                    {
                        DrawLine(verticalLinePrefab, new Vector3((left + right) / 2, 0, top), new Vector3(right, 0, top));
                    }

                    // Draw right border line if necessary
                    if (j < numCols - 1 && grid[i, j + 1] == -1)
                    {
                        DrawLine(horizontalLinePrefab, new Vector3(right, 0, (top + bottom) / 2), new Vector3(right, 0, bottom));
                    }

                    // Draw bottom border line if necessary
                    if (i < numRows - 1 && grid[i + 1, j] == -1)
                    {
                        DrawLine(verticalLinePrefab, new Vector3((left + right) / 2, 0, bottom), new Vector3(right, 0, bottom));
                    }
                }
            }
        }
    }

    private void DrawLine(Image linePrefab, Vector3 start, Vector3 end)
    {
        GameObject line = Instantiate(linePrefab.gameObject, Vector3.zero, Quaternion.identity);
        line.transform.SetParent(transform);
        LineRenderer lineRenderer = line.GetComponent<LineRenderer>();

        lineRenderer.positionCount = 2;
        lineRenderer.SetPositions(new Vector3[] { start, end });
    }
}

The problem is that nothing appears on the screen.

Normally, the code shouldn’t draw lines between empty cells.

If you can correct my code,

Kind regards,

A+

I don’t see how the above brute-force approach to simply draw a regular grid is going to be useful long-term for you. Nothing here should involve a lot of persistent GameObject and components if it’s simply just drawing.

You don’t even have to use the Tilemap system, you can use the Grid component on its own (Tilemap uses this too) to define your layout then instantiate/draw things at the positions you’re interested in. You can get cell/world positions using one of the many conversion methods here:

As above though, you can also use the Tilemap system that uses the Grid to place tiles and/or GameObjects too.

I can’t create empty cells in the grid (with your code).

This is what I want to draw

:

I don’t think you should draw lines if 2 adjacent squares are empty horizontaly and verticaly.

Thanks for your help,

A+

Sorry, are you replying to me? I didn’t provide you with any code.

I know, I’m able to read your previous post above.

If you are trying to create the above grid with code, that is the most difficult and most-complicated way to do it.

If you don’t want to use the existing TileMap system, just make a simple tile-based editor, like this one:

https://www.youtube.com/watch?v=gD5EQyt7VPk

Then you can put holes anywhere you want.

You don’t want to start fiddling with code for creating content until you’re completely comfortable writing editors.

I think his problem is not understanding he’ll have to do 2 grid iterations. But most tile based grids are actually just one sprite, and they have their own borders on their image, so you only focus center of tile(or bottom left) placement.

But what I do for the end tiles to be borders themselves(or edge map logic) is:

if (gridPos.y == 0 || gridPos.x == 0 ||
        gridPos.y == mapHeight - 1 || gridPos.x == mapWidth - 1)
    { DoEdgeLogic(); }

Hello,

I’m not in favor of using the Tile Map (I have to create 100 grids, and that’s a bit much).

Here’s my problem:

and my code :

    void DrawGrid()
    {
        Vector3 startPosition = transform.position;

        float horizontalOffset = Colonnes * cellSize * 0.5f - cellSize * 0.5f;
        float verticalOffset = Lignes * cellSize * 0.5f - cellSize * 0.5f;

        for (int row = 0; row <= Lignes; row++)
        {
            for (int col = 0; col <= Colonnes; col++)
            {
                Vector3 position = startPosition + new Vector3(col * cellSize - horizontalOffset, -row * cellSize + verticalOffset);

                if (col < Colonnes)
                {
    //            if (col < Colonnes - 1 && (Grille[row, col] != -1 || Grille[row, col + 1] != -1))
                    {
                        CreateLine(verticalLinePrefab, position + new Vector3(cellSize / 2, 0, 0));
                    }
                }

                if (row < Lignes)
                {
                     CreateLine(horizontalLinePrefab, position - new Vector3(0f, cellSize / 2, 0f));
                }
            }
        }
    }

    void CreateLine(Image linePrefab, Vector3 position)
    {
        Image newLine = Instantiate(linePrefab, position, Quaternion.identity);
        newLine.transform.SetParent(transform);
    }
}

As you can see from the image, the code draws a vertical line between 2 empty boxes.

I put the following instruction:

if (col < Columns - 1 && (Grid[row, col] != -1 || Grid[row, col + 1] != -1))

But this makes a part of the grid disappear.

Thanks for your help,

A+

It would take one tilemap, one rule tile, and some code to generate tiles at coordinates.

That’s a whole lot simpler than what you’re trying to accomplish.

Sorry, but with your Tile Map, you might as well create UI Images with images of the grids.

I think it would be better with a bit of simple code.

Kind regards,

A+