Réponses:
Pour obtenir un tableau avec toutes les tuiles d'une zone rectangulaire de votre tilemap, utilisez tilemap.GetTilesBlock(BoundsInt bounds)
. Vous obtiendrez un tableau unidimensionnel de tuiles, vous devez donc savoir par vous-même quand la prochaine rangée de tuiles commence. Toutes les cellules vides seront représentées avec une null
valeur.
Si vous voulez toutes les tuiles, utilisez tilemap.cellBounds
. Cela vous donne un BoundsInt
objet qui couvre toute la zone utilisée du tilemap. Voici un exemple de script qui récupère toutes les tuiles du Tilemap sur le même objet de jeu et répertorie les tuiles avec leurs coordonnées:
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)");
}
}
}
}
}
En ce qui concerne les limites et pourquoi vous pourriez obtenir plus de tuiles que vous attendez: Conceptuellement, les Tilemaps Unity ont une taille illimitée. Ils cellBounds
poussent au besoin lorsque vous peignez des carreaux, mais ils ne rétrécissent plus si vous les effacez. Ainsi, lorsque votre jeu a une taille de carte bien définie, vous pourriez obtenir des surprises si vous vous glissez lors de la modification des cartes. Il existe trois façons de contourner ce problème:
tilemap.CompressBounds()
pour restaurer les limites des tuiles les plus éloignées (en espérant que vous vous souveniez de les effacer)bounds
vous-même l' objet au new BoundsInt(origin, size)
lieu de vous y fier cellBounds
.tilemap.origin
et tilemap.size
sur les valeurs souhaitées, puis appelez tilemap.ResizeBounds()
.Voici une autre façon de le faire avec .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);
}
Lors de la détermination de la façon d'obtenir toutes les tuiles personnalisées de Tilemap et en raison de la méthode ITilemap
non GetTilesBlock
mentionnée dans les réponses, je suggère d'ajouter une méthode d'extension comme celle-ci (2D uniquement):
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();
}
}
Dans ce cas, si vous avez, supposons, des tuiles personnalisées TileRoad, héritées de Tile ou TileBase, vous pouvez obtenir toutes les tuiles TileRoad avec appel:
TileBase[] = tilemap.GetTiles<RoadTile>();
Pour ITilemap, nous pouvons changer le paramètre (this Tilemap tilemap)
en (this ITilemap tilemap)
mais je n'ai pas vérifié cela.
GetComponent<Tilemap>()
.