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 nullvalore.
Se vuoi tutte le tessere, usa tilemap.cellBounds. Questo ti BoundsIntdà 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 cellBoundscrescere 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)boundsoggetto con te stesso new BoundsInt(origin, size)invece di fare affidamento cellBounds.tilemap.origine tilemap.sizesui 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 ITilemapnon GetTilesBlockindicato 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>().