Risposte:
Per ottenere una matrice con tutte le tessere da un'area rettangolare della piastrella, utilizzare tilemap.GetTilesBlock(BoundsInt bounds)
. Otterrai una matrice unidimensionale di tessere, quindi devi sapere da solo quando inizia la prossima fila di tessere. Qualsiasi cella vuota verrà rappresentata con un null
valore.
Se vuoi tutte le tessere, usa tilemap.cellBounds
. Questo ti BoundsInt
dà un oggetto che copre l'intera area utilizzata della tilemap. Ecco uno script di esempio che ottiene tutte le tessere dalla Tilemap sullo stesso oggetto di gioco ed elenca le tessere con le loro coordinate:
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)");
}
}
}
}
}
Per quanto riguarda i limiti e il motivo per cui potresti ottenere più riquadri di quanto ti aspetti: concettualmente, le tessere Unity hanno dimensioni illimitate. Il cellBounds
crescere come necessario quando si dipinge piastrelle, ma non ridursi ancora se li si cancella. Quindi, quando il tuo gioco ha una dimensione della mappa ben definita, potresti avere delle sorprese se scivoli durante la modifica delle mappe. Esistono tre modi per aggirare questo problema:
tilemap.CompressBounds()
per ripristinare i limiti alle tessere più esterne (sperando che ti sia ricordato di cancellarle)bounds
oggetto con te stesso new BoundsInt(origin, size)
invece di fare affidamento cellBounds
.tilemap.origin
e tilemap.size
sui valori desiderati e quindi chiamare tilemap.ResizeBounds()
.Ecco un altro modo per farlo .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 la ricerca di come ottenere tutte le tessere personalizzate da Tilemap e a causa del metodo ITilemap
non GetTilesBlock
indicato nelle risposte, suggerisco di aggiungere un metodo di estensione come questo (solo 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();
}
}
In questo caso, se hai, supponi, tessere personalizzate TileRoad, ereditate da Tile o TileBase, puoi ottenere tutte le tessere TileRoad con la chiamata:
TileBase[] = tilemap.GetTiles<RoadTile>();
Per ITilemap possiamo cambiare il parametro (this Tilemap tilemap)
in (this ITilemap tilemap)
ma non l'ho verificato.
GetComponent<Tilemap>()
.