Jon Dier Jon Dier - 9 months ago 43
C# Question

Using two grids for different purposes in Unity

I am creating a 2D virtual boardgame in Unity, which has following setup:
enter image description here

This is put in manually as gameObjects, which is highly inconvenient when you need to create multiple mechanics.

For now I need to create 2 mechanics:

  • Being able to determine which tiles are reachable for the player (decided by a dice)

  • Being able to rotate any 3x3 object by its center, like this one:

enter image description here

Note: The big white squares are corner-pieces, and won't be used for any mechanic.

My current state of mind is to make a grid of tiles, then on top of that a 3x3 grid.

  1. Is this the proper way to go around this?

  2. How would I first create a tile-grid, then a 3x3 grid based on that tile grid?

I've tried messing around with creating the grid from a gameObject or IEnumerator, which either led to unsuccesful attempts, or extreme performance issues for my PC.

Answer Source

Here is my idea.

  1. Have a NxN grid consisting of all the game tiles.
  2. Have one 3x3 grid with 9 preloaded tiles and disable it at start. it is never a good idea to instantiate game objects at run-time.
  3. When user clicks a tile (Let's call the 9 tiles which lay around the clicked tile from the NxN grid, sub-grid):
    • Move the 3x3 grid onto the sub-grid
    • Hide the 9 tiles from the sub-grid
    • Enable the 3x3 grid
    • Enable/Disable the 3x3 grid tiles according to the sub-grid tiles
    • Start the animation on the 3x3 grid (rotate the whole 3x3 grid) (1)
    • Disable the 3x3 grid
    • Enable/Disable the sub-grid tiles according to the 3x3 grid tiles (*)
    • Show the sub-grid again
    • Undo the rotation of 3x3 grid (*)


(*) When rotating the 3x3 grid the index of each tile is not valid anymore. because the 3x3 grid is rotated but not its tiles. so you need to translate the indices in the 3x3 grid to match the sub-grid indices. it's better not to change the actual indices but to just convert them before use. and remember to undo the rotation when it's done.

I would suggest this approach for translating indices:

struct XY { 
    public int x; 
    public int y; 
    public XY(int X, int Y){x=X;y=Y;}

//no need for this one, it's just here to have a better understanding
static XY[,] _rotateNoneIdx = new XY { 
   { new XY(0,0), new XY(1,0), new XY(2,0) },
   { new XY(0,1), new XY(1,1), new XY(2,1) },
   { new XY(0,2), new XY(1,2), new XY(2,2) }
//translating matrix for translating left-rotated 3x3 grid tiles
static XY[,] _rotateLeftIdx = new XY { 
   { new XY(2,0), new XY(2,1), new XY(2,2) },
   { new XY(1,0), new XY(1,1), new XY(1,2) },
   { new XY(0,0), new XY(0,1), new XY(0,2) }
//translating matrix for translating right-rotated 3x3 grid tiles
static XY[,] _rotateRightIdx = new XY { 
   { new XY(0,2), new XY(0,1), new XY(0,0) },
   { new XY(1,2), new XY(1,1), new XY(1,0) },
   { new XY(2,2), new XY(2,1), new XY(2,0) }

//this method translates the rotated tile indices to actual indices
static XY TranslateIndex(XY beforeRotateXY, bool isRotateLeft)
    if(isRotateLeft) return _rotateLeftIdx[beforeRotateXY.x, beforeRotateXY.y];
    return _rotateRightIdx[beforeRotateXY.x, beforeRotateXY.y];

I haven't test this code so you may need to try swapping the left and right.