Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. Dismiss Notice

An in-game editable 2D grid system (array/list)

Discussion in 'Scripting' started by Ichbinbin, Jan 6, 2022.

  1. Ichbinbin

    Ichbinbin

    Joined:
    Mar 30, 2021
    Posts:
    8
    I'm trying to create a 2D grid system which can be editted in-game, so things can be removed and added to the grid at all times. This grid is used to declare adjecent tiles for all my tiles. The problem is that these tiles are player built in-game and I'm thus unable to use an array.

    This is my grid system builder I made using an array:

    Code (CSharp):
    1. GameObject [,] tileArray;
    2.     public GameObject tile;
    3.     public int gridXSize;
    4.     public int gridYSize;
    5.     public float tileSize;
    6.  
    7.     void Start ()
    8.     {
    9.         tileArray = new GameObject [gridXSize,gridYSize];
    10.         Transform grid = transform.GetChild(0);
    11.         float tempSize = tileSize * tile.transform.localScale.x;
    12.         for (int x = 0; x < gridXSize; x++)
    13.         {
    14.             for (int y = 0; y < gridYSize; y++)
    15.             {
    16.                 GameObject newTile = Instantiate(tile, new Vector3(grid.position.x + x * tempSize, grid.position.y + y * tempSize, 0), Quaternion.identity, grid);
    17.                 newTile.GetComponent<Machine>().placement = GetComponent<Placement>();
    18.                 tileArray[x, y] = newTile;
    19.             }
    20.         }
    21.  
    22.         for (int a = 0; a < gridXSize; a++)
    23.         {
    24.             for (int b = 0; b < gridYSize; b++)
    25.             {
    26.                 if (a + 1 < gridXSize)
    27.                 {
    28.                     tileArray[a, b].GetComponent<Machine>().right = tileArray[a + 1, b];
    29.                 }
    30.                 if (a - 1 >= 0)
    31.                 {
    32.                     tileArray[a, b].GetComponent<Machine>().left = tileArray[a - 1, b];
    33.                 }
    34.                 if (b + 1 < gridYSize)
    35.                 {
    36.                     tileArray[a, b].GetComponent<Machine>().up = tileArray[a, b + 1];
    37.                 }
    38.                 if (b - 1 >= 0)
    39.                 {
    40.                     tileArray[a, b].GetComponent<Machine>().down = tileArray[a, b - 1];
    41.                 }
    42.             }
    43.         }
    44.     }
    The last bit is to determine adjecent tiles for tiles which players build machines on, which is absolutly nessicary for the machines and is the cause of this problem. The machine building happends through this script:

    Code (CSharp):
    1.  
    2.     public Placement placement;
    3.  
    4.     public GameObject up;
    5.     public GameObject down;
    6.     public GameObject left;
    7.     public GameObject right;
    8.  
    9.     public string type;
    10.  
    11.     public string adjecents;
    12.  
    13. void OnMouseOver ()
    14.     {
    15.         if (type == "Tile" && placement.selectedMachine != null)
    16.         {
    17.             placement.selectedMachine.transform.position = transform.position;
    18.         }
    19.  
    20.         if (placement.building == true)
    21.         {
    22.             if (type == "Tile" && placement.selectedMachine != null)
    23.             {
    24.                 GetComponent<SpriteRenderer>().sprite = placement.selectedMachine.GetComponent<SpriteRenderer>().sprite;
    25.                 GetComponent<SpriteRenderer>().color = placement.selectedMachine.GetComponent<SpriteRenderer>().color;
    26.                 GetComponent<SpriteRenderer>().sortingOrder = placement.selectedMachine.GetComponent<SpriteRenderer>().sortingOrder;
    27.                 GetComponent<Machine>().rotations = placement.selectedMachine.GetComponent<Machine>().rotations;
    28.                 GetComponent<Machine>().type = placement.selectedMachine.GetComponent<Machine>().type;
    29.                 GetComponent<Machine>().importRate = placement.selectedMachine.GetComponent<Machine>().importRate;
    30.                 GetComponent<Machine>().item = placement.selectedMachine.GetComponent<Machine>().item;
    31.                 GetComponent<Machine>().items = placement.selectedMachine.GetComponent<Machine>().items;
    32.                 RotateMachine();
    33.                 placement.UpdateGrid();
    34.                 if (type == "Importer")
    35.                 {
    36.                     InvokeRepeating("ImportItem", 0f, importRate);
    37.                 }
    38.             }
    39.         }
    40.  
    41.         if (placement.destroying == true)
    42.         {
    43.             GetComponent<SpriteRenderer>().sprite = placement.tile.GetComponent<SpriteRenderer>().sprite;
    44.             GetComponent<SpriteRenderer>().color = placement.tile.GetComponent<SpriteRenderer>().color;
    45.             GetComponent<SpriteRenderer>().sortingOrder = 0;
    46.             GetComponent<Machine>().type = "Tile";
    47.             placement.UpdateGrid();
    48.             item = null;
    49.         }
    50.     }
    51.  
    52.     void OnMouseDown ()
    53.     {
    54.         if (placement.destroyment == true)
    55.         {
    56.             if (type != "Tile")
    57.             {
    58.                 GetComponent<SpriteRenderer>().sprite = placement.tile.GetComponent<SpriteRenderer>().sprite;
    59.                 GetComponent<SpriteRenderer>().color = placement.tile.GetComponent<SpriteRenderer>().color;
    60.                 GetComponent<SpriteRenderer>().sortingOrder = 0;
    61.                 GetComponent<Machine>().type = "tile";
    62.                 placement.UpdateGrid();
    63.                 item = null;
    64.             }
    65.             placement.destroying = true;
    66.         }else
    67.         {
    68.             placement.building = true;
    69.         }
    70.     }
    71.     void OnMouseUp ()
    72.     {
    73.         placement.building = false;
    74.         placement.destroying = false;
    75.     }
    Placement is the grid building grid and Machine is this script.
    Because I use an array here, I can't add or remove machines from the array in-game, so my solution was to instead create the array with tiles at first and than in-game replace the tiles with machines by editing their properties in the script. This system works, but it requires a lot of messy code, because I can't just copy all properties of the machine I want to place to the tile I want to place it on, I have to specificly set every property of the tile nessicary to the matching property of the machine I want to place.

    I hope someone else has a solution to this problem, which is mainly how to create an array or list that can be edited in in-gametime, also, with this solution I would get rid of the replcace-tile-with-machine system and just instantiate the machines on the tiles.

    Also if you need the entire scripts, they are attached to this thread,
    note tho: not everything in them is important for this problem.
     

    Attached Files:

  2. GroZZleR

    GroZZleR

    Joined:
    Feb 1, 2015
    Posts:
    3,201
    This seems more like a data management issue? You either need to make your array out of something more meaningful than GameObjects, like Machine[,] or create a custom Cell class that describes each cell in your grid in a more meaningful way, like:
    Code (csharp):
    1.  
    2. // very rough psuedo-ish code:
    3. public class Cell
    4. {
    5.    public int x, y;
    6.    public List<Machine> machines = new List<Machine>();
    7. }
    8.  
    9. public class Grid
    10. {
    11.    public Cell[,] cells;
    12.  
    13.    public Grid(int size)
    14.    {
    15.        // create your cells array
    16.        // create each cell instance and fill in the appropriate data
    17.    }
    18.  
    19.    public Cell GetCell(int x, int y)
    20.    {
    21.        // TODO: sanitize the data so you can't go out of bounds etc
    22.        return cells[x, y];
    23.    }
    24. }
    25.  
    Then you can query the world in more meaningful ways:
    Code (csharp):
    1.  
    2.  
    3. // are there machines to the north?
    4. Cell north = grid.GetCell(currentCell.x, currentCell.y - 1);
    5.  
    6. if(north != null)
    7. {
    8.    foreach(Machine machine in north.machines)
    9.    {
    10.        // do whatever
    11.    }
    12. }
    13.  
     
  3. Ichbinbin

    Ichbinbin

    Joined:
    Mar 30, 2021
    Posts:
    8
    Thank you for your help!
    I've now made it so that first the tiles generate and than when a machine is built on them, the machine will be linked to the tile it's on so that I can use the adjecents data to check if there are other machines on the adjecent tiles so I can set the sprite correctly.
     
    GroZZleR likes this.