I am currently working on a game where we have designed the levels using the experimental Tilemap feature and painting with the brush.
I am currently working on a pathfinder, and this requires examining each of the tiles in the tilemap.
Problem is, I don’t know how to do it. I’ve scanned the APIs over and over again but there doesn’t seem to be any apparent way to acquire a TileBase’s position
The farthest I’ve gotten is acquiring an array of the TileBases using
But there aren’t any coordinates associated with that! I know the cellBounds provides some sort of positions but using the coordinates below I’m not sure I’m selecting the actual tiles. And if I were, how would I get the position in the world?
int colNumbers = size.yMax - size.yMin;
int rowNumbers = size.xMax - size.xMin;
for (int col = colNumbers; col >= 0; col--)
{
for (int row = 0; row <= rowNumbers; row++)
{
TileBase currentTile = terrain.GetTile(new Vector3Int(row, col, 0));
}
}
TileBase doesn’t have a position, it’s a class that’s representing the type of the tile.
If you need to go thrugh all the tiles, simply iterate through all the coordinates on the grid beginning from the tilemap.origin up to tilemap.origin + tilemap.size. At each coordinate you can retrieve the TileBase that’s associated with it, and do whatever you need to do.
To get the position in the world, given the integer coordinates use the following.
I had a lot of trouble with this recently, but eventually managed to get it to work. Here’s how I got a list of all positions on a tilemap:
public Tilemap tileMap = null;
public List<Vector3> availablePlaces;
void Start () {
tileMap = transform.GetComponentInParent<Tilemap>();
availablePlaces = new List<Vector3>();
for (int n = tileMap.cellBounds.xMin; n < tileMap.cellBounds.xMax; n++)
{
for (int p = tileMap.cellBounds.yMin; p < tileMap.cellBounds.yMax; p++)
{
Vector3Int localPlace = (new Vector3Int(n, p, (int)tileMap.transform.position.y));
Vector3 place = tileMap.CellToWorld(localPlace);
if (tileMap.HasTile(localPlace))
{
//Tile at "place"
availablePlaces.Add(place);
}
else
{
//No tile at "place"
}
}
}
}
Feel free to use my code however you want!
An alternative, which I did before I wrote that code, is creating a raycast from the sky, or anything that can detect collides, and testing each location in a given range with it.
As for the pathfinding itself, I wrote some A* that uses “availablePlaces”
Are the same tile but different locations not unique? So if I place a tile at 0,0 and the same tile at 0,1. Unity doesn’t see that as 2 separate tiles but the same?
I’ve spent over 6 hours trying to create a floodfill algorithm only to find out every time I “GetTile” it doesn’t matter at what position it always returns the same tile.
The way I’m doing it is covering the area with a RoomTile. RoomTiles have a Room variable, just says what Room that tile is a part of. So if my floodfill says this RoomTile needs to be a different Room I set that RoomTile’s Room variable but this also affects every other RoomTile.
Correct: It is the same Tile asset in every cell. We do not instantiate Tile asset for every cell, we simply refer to the same Tile asset in the project many times
Your intuition of storing per-cell data into Tile is understandable, but it isn’t how this system is designed to work. You have to store your per-cell data some other way. We will offer storage component called GridInformation as open-source add-on before 2017.2 comes out. You can also make your own custom component to store that data if you want, but Tile(s) are only meant for rendering & physics, not data.
Okay cool. I mean that actually makes sense performance wise but it was just me being an idiot and not realizing what was happening. Thanks. Can’t wait for GridInformation component.
Hey thank you! That its working well for me, but this show all positions, even if its painted or not, how can I do something only if its a filled tile? I mean, if I paint a tile, and after that I use the erase tool, how can I ignore this erased tile in this kind of loop?
I was not able to understand how to use GridInformation tho
Thank you in advance
@
Seems that the DDaddySupreme solution will help me, thank you