Respostas:
Para obter uma matriz com todos os blocos de uma área retangular do seu mapa de blocos, use tilemap.GetTilesBlock(BoundsInt bounds). Você obterá uma matriz unidimensional de blocos, portanto precisará saber quando a próxima linha de blocos iniciar. Quaisquer células vazias serão representadas com um nullvalor.
Se você quiser todas as peças, use tilemap.cellBounds. Isso BoundsIntgera um objeto que cobre toda a área usada do mapa de peças. Aqui está um exemplo de script que obtém todos os blocos do Tilemap no mesmo objeto de jogo e lista os blocos com suas coordenadas:
using UnityEngine;
using UnityEngine.Tilemaps;
public class TileTest : MonoBehaviour {
void Start () {
Tilemap tilemap = GetComponent<Tilemap>();
BoundsInt bounds = tilemap.cellBounds;
TileBase[] allTiles = tilemap.GetTilesBlock(bounds);
for (int x = 0; x < bounds.size.x; x++) {
for (int y = 0; y < bounds.size.y; y++) {
TileBase tile = allTiles[x + y * bounds.size.x];
if (tile != null) {
Debug.Log("x:" + x + " y:" + y + " tile:" + tile.name);
} else {
Debug.Log("x:" + x + " y:" + y + " tile: (null)");
}
}
}
}
}
Em relação aos limites e por que você pode obter mais peças do que o esperado: conceitualmente, os Unity Tilemaps têm um tamanho ilimitado. A cellBoundscrescer conforme necessário, quando você pintar azulejos, mas eles não encolher novamente, se você apagá-las. Portanto, quando o seu jogo tiver um tamanho de mapa bem definido, você poderá ter algumas surpresas se escorregar durante a edição de mapas. Existem três maneiras de solucionar esse problema:
tilemap.CompressBounds()para restaurar os limites para os blocos mais extremos (esperando que você se lembre de apagá-los)boundsobjeto com você em new BoundsInt(origin, size)vez de confiar cellBounds.tilemap.origine tilemap.sizecom os valores desejados e depois chame tilemap.ResizeBounds().Aqui está outra maneira de fazer isso com .cellBounds.allPositionsWithin
public Tilemap tilemap;
public List<Vector3> tileWorldLocations;
// Use this for initialization
void Start () {
tileWorldLocations = new List<Vector3>();
foreach (var pos in tilemap.cellBounds.allPositionsWithin)
{
Vector3Int localPlace = new Vector3Int(pos.x, pos.y, pos.z);
Vector3 place = tilemap.CellToWorld(localPlace);
if (tilemap.HasTile(localPlace))
{
tileWorldLocations.Add(place);
}
}
print(tileWorldLocations);
}
Durante a descoberta de como obter todos os blocos personalizados do Tilemap e, devido ao método ITilemapnão GetTilesBlockmencionado nas respostas, sugiro adicionar um método de extensão como este (somente 2D):
public static class TilemapExtensions
{
public static T[] GetTiles<T>(this Tilemap tilemap) where T : TileBase
{
List<T> tiles = new List<T>();
for (int y = tilemap.origin.y; y < (tilemap.origin.y + tilemap.size.y); y++)
{
for (int x = tilemap.origin.x; x < (tilemap.origin.x + tilemap.size.x); x++)
{
T tile = tilemap.GetTile<T>(new Vector3Int(x, y, 0));
if (tile != null)
{
tiles.Add(tile);
}
}
}
return tiles.ToArray();
}
}
Nesse caso, se você tiver, suponha, o tileRoad personalizado, herdado de Tile ou TileBase, poderá obter todos os tiles de TileRoad com a chamada:
TileBase[] = tilemap.GetTiles<RoadTile>();
Para o ITilemap , podemos alterar o parâmetro (this Tilemap tilemap)para, (this ITilemap tilemap)mas não verifiquei isso.
GetComponent<Tilemap>().