1
\$\begingroup\$

I am learing Unity and for now trying to implement a simply pathfinding alogorithm in a simply 2D isometric diamond-shaped tilemap.

Recently I learned a way how to rotate tilemap and I already have a question.

My rotation algorithm works as follows:

  1. I create a Dictionary Dictionary<Vector3Int, TileBase> for storing tiles.
  2. Then I iterate through my tilemap and implement a 90-degrees rotation operator as (x, y) --> (-y, x). And save new tiles position in a Dictionary.
  3. Then I clear all tiles by calling tilemap.ClearAllTiles()
  4. And then set tiles again from Dictionary.

f

foreach (var item in tilesPositions)
{
tilemap.SetTile(item.Key, item.Value);
}
tilemap.CompressBounds();

Honestly I am worry a little about implementation of the pathfinding. As I understand, this algorithm receive start position and end position and made some calculation for mob's to move from start to end

Let imagine I rotate my tilemap making (x, y) --> (-y, x) for all tiles Will this procdeure broke a pathfinding algorithm?

And most of all, is the rotation of tilemap which maded with recalculation position for all tiles the best way to do 90 degree rotation for an isometric game?

\$\endgroup\$
1
  • \$\begingroup\$ Consider phrasing it like this: "If I can turn my phone camera 90 degrees, does Google Maps have to recalculate the directions to my house?". No. The roads that the directions are tracing are part of the structure of the world. Turning your camera changes the transformation of that structure to your screen, but it doesn't literally upend the neighbourhood. You can structure your game the same way, separating the "logical" position of a landmark from its current displayed position according to the camera rotation. \$\endgroup\$
    – DMGregory
    Feb 5 at 20:44

1 Answer 1

1
\$\begingroup\$

You need to decouple/disconnect different parts of your application.

Ideally, you want to have some object representing the board in memory which only deals with gameplay-specific concerns (placing pieces, movement, etc).

Whilst it's possible to use a Dictionary<Vector3Int, TileBase> for this, it's not actually a very useful format for finding (or reasoning about) adjacent tiles.

You might be better off creating a 2-dimensional array of TileBase...

var board = new TileBase[10,10];

Then you can refer to the tiles by coordinate (0-indexed) board[0,0], board[8,9], etc.

This will make it a lot easier to find the next tile when path finding.


Entirely separate to that, you have a requirement to display that board in the UI.

If possible, you can just pull the data directly from the board to recreate the UI elements as needed.

If you absolutely must have it in the form of a Dictionary<Vector3Int, TileBase>, you can convert from the board to your dictionary format.

If you do that step using a couple of nested loops as shown below

var dictionary = new Dictionary<Vector3Int, TileBase>();

for (int x = 0; x < board.GetLength(0); x++)
{
    for (int y = 0; y < board.GetLength(1); y++)
    {
        if (board[x, y] != null)
        {
            dictionary[new Vector3Int(x, y, 0)] = board[x, y];
        }
    }
}

Then it becomes trivially simple to rotate/flip the board by tweaking the values written to the dictionary (or even by playing with the loop order/variables)

All your path finding is now working on board alone, so doesn't have to worry about rotation or any other UI-level concerns.

p.s. There's a Vector2Int if you only need 2D coordinates.

\$\endgroup\$
3
  • 1
    \$\begingroup\$ Maaaaan this is the most useful advice I've ever heard! I do not even think about separation the logical structure and visualization. It seems that I can even derive a class for my tiles from TileBase and store in that 2-D array instances of this class with all tile data that I need. I would give you a 10 reputation points for this advice but I can't bcz I am a newly registered. \$\endgroup\$
    – Valeriy
    Feb 6 at 19:19
  • \$\begingroup\$ No worries about the rep, I'm just glad I could help. \$\endgroup\$
    – Basic
    Feb 7 at 4:33
  • \$\begingroup\$ One more thing to consider... Instead of your board being a 2D array, make it a class with a Tiles propery... public class Board {public TileBase[,] Tiles {get;set;}} and put the array there. Then you can attach other board-related properties to the Board class itself (Turn info, map name, etc) . If the Board and TileBase classes are serialisable, you can now dump the entire board state to disk (Save/Load game) and/or your logs/phone-home error reporting. \$\endgroup\$
    – Basic
    Feb 7 at 19:56

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .