For loop mistake

Hey,
I have an array of strings “grid”, each of its numbers represent a cell (in editor) and the string value says what is located on this number/cell. (That actually doesn’t matter)

I use this for loop to assign the values “Ground” in a square (scale is 11,11). But it doesn’t work and just assigns the values from the upper left corner and goes just right (I think 121 times (11 times 11))

Vector2 x0y0 = new Vector2(); // This is the upper left corner of a 2D cube

    void Start()
    {
        int x = (int)x0y0.x, y = (int)x0y0.y;

        for (int aY = 0; aY <= (int)transform.localScale.y; y++, aY++) // When the left-to-right assignment is over, goes down on 1 cell, so it can assign the next row
        {
            for (int aX = 0; aX <= (int)transform.localScale.x; x++) // Assigns from the left of the object, to its right
            {
                gameGrid.grid[x, y] = "Ground";
                print(x + " " + y);
            }

            x = (int)x0y0.x; // This value was "on the right" of the object. Refreshes so it will "go to the left" again to assign the next row
        }
    }

I hope I explained all clear, I’m a beginner at programing.

Thank you!

Hi,
why are you using a Vector2 x0y0? As far as i can see, you never actually assign its values, so it’s just (0,0), for which we have Vector2.zero. Then, you created a very weird nested for loop. For what do you need aY and aX, or x and y? One of those pairs should be enough.

I’m also not entirely sure what it is you are tryng to do. As i understand it, you simply want to fill a multidimensional array with the string “Ground”? That’s pretty simple actually:

for(int x = 0; x < yourXSize; x++){
    for(int y = 0; y < yourYSize; y++){
        grid[x,y] = "Ground";
    }
}

If that’s the case, i also doubt that (int)transform.localScale is what you want to use, but that may depend on the sceneario.

Oh and also; unless there is a good reason for using strings, it doesnt seem like a good idea. Use numbers or an Enum instead. If you need help with that just ask, but it’s a bit off topic for now i guess.

Hope this helps! :slight_smile:

I’m trying to make a grid system, so my “grid” array represents world coordinates. :smile: For example, if there is a 1,1 cube on position 12,20 in the game and it should do the tasks of a Ground, it stores in the array “grid” on [12,20] as string “Ground” (It will help me much later, so I’m doing it this way)
I wanted to make a script that will automatically assign the "Ground"s under all the cells that the object is placed on.
So if we have a Cube with scale 3,3 and its Upper Left Corner placed under coordinates 10,10, the script should assign the value “Ground” to these “numbers”(or how do we call it xd) in that order: 10.10 , 11.10, 12.10, 10.11, 11.11, 12.11, 12.10, 12.11, 12.12. (If the script works correctly). So I’m assigning the x0y0 in the inspector, and that’s the point from which the calculations (for loop) are starting

I know that you are saving “Block Types” in your grid. What i was talking about it why you are saving them as strings. This is neither memory efficient, nor a good idea for maintainability, as you can easily cause bugs with typos that the compiler wont be able to help you with. That’s why i suggested using an Enum. It would still allow you to save a YourEnum.Ground at that position, make it impossible to introduce typos, and take up only as much memory as an int. So unless you need to dynamically edit those strings later at runtime, i dont really see a reason for using strings.

Are cubes the only thing you are placing? Because not every object has a default size of (1,1,1). Meaning, localScale does not always represent the size in total units. A plane, for example, has a default size of 10 in all directions if i remember correctly, so the scale would be 1, but its size would be 10. Other objects may have similar problems.
And what do you do when default size + scale result in an uneven value, like 5.5 units? Simply cut it by casting? Depending on what exactly you intend to do, there may be more appropriate solutions.
Also, are those cubes snapped to your grid? Or can they be placed anywhere and you just try to find the most reasonable coordinate in your grid by casting to int?

Either way, the most robust approach is probably to calculate the bottom-left-most coordinate of the object, as well as its width and length. You can do this rather easily by getting the Bounds of the object (for example from its mesh):
https://docs.unity3d.com/ScriptReference/Bounds.html

The bounds.min would already represent the bottom-left-most coordinate. It’s width and length can easily be calculated from the extents (Vector3). Now you only need to think about whether casting to an int is actually what you want to do. Maybe Mathf.Round is better for your situation (either for the most appropriate grid coordinate, or the size)?
Anyways, as soon as you got these values, simply run the loops i posted above like this:

for(int x = xMin; x < xExtent; x++){
    for(int y = yMin; y < yExtent; y++){
        grid[x,y] = "Ground";
    }
}

This makes it so that in your example the grid underneath the 3x3 cube would be filled with “Ground”. But again, i’d highly suggest using an enum, so replace grid[x,y] = “Ground” with grid[x,y] = YourEnum.Ground, with an Enum like this:

enum YourEnum
{
    Ground,
    NotGround,
    ... // obviously representing other values
};

Thank you, that is really helpful !