Jawaban:
Untuk mendapatkan array dengan semua ubin dari area persegi panjang tilemap Anda, gunakan tilemap.GetTilesBlock(BoundsInt bounds)
. Anda akan mendapatkan array ubin satu dimensi, jadi Anda perlu tahu sendiri kapan baris ubin berikutnya dimulai. Setiap sel kosong akan diwakili dengan null
nilai.
Jika Anda ingin semua ubin, gunakan tilemap.cellBounds
. Ini memberi Anda BoundsInt
objek yang mencakup seluruh area tilemap yang digunakan. Berikut ini contoh skrip yang mendapatkan semua ubin dari Tilemap pada objek game yang sama dan mencantumkan ubin dengan koordinatnya:
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)");
}
}
}
}
}
Mengenai batasan dan mengapa Anda mungkin mendapatkan ubin lebih dari yang Anda harapkan: Secara konseptual, Unity Tilemaps memiliki ukuran yang tidak terbatas. The cellBounds
tumbuh yang diperlukan ketika Anda cat ubin, tetapi mereka tidak menyusut lagi jika Anda menghapusnya. Jadi saat gim Anda memiliki ukuran peta yang terdefinisi dengan baik, Anda mungkin akan mendapatkan kejutan jika pernah terpeleset saat mengedit peta. Ada tiga cara untuk mengatasi masalah ini:
tilemap.CompressBounds()
untuk mengembalikan batas ke ubin terluar (berharap Anda ingat untuk menghapusnya)bounds
objek sendiri dengan new BoundsInt(origin, size)
bukannya mengandalkan cellBounds
.tilemap.origin
dan tilemap.size
ke nilai yang diinginkan lalu panggil tilemap.ResizeBounds()
.Berikut ini cara lain untuk melakukannya .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);
}
Selama mencari tahu cara mendapatkan semua ubin khusus dari Tilemap dan karena ITilemap
belum GetTilesBlock
metode yang disebutkan dalam jawaban saya sarankan untuk menambahkan metode ekstensi seperti ini (hanya 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();
}
}
Dalam hal ini jika Anda memiliki, misalkan, ubin TileRoad kustom, yang diwarisi dari Tile atau TileBase, maka Anda bisa mendapatkan semua ubin TileRoad dengan panggilan:
TileBase[] = tilemap.GetTiles<RoadTile>();
Untuk ITilemap kita dapat mengubah parameter (this Tilemap tilemap)
untuk (this ITilemap tilemap)
tetapi saya tidak memeriksa itu.
GetComponent<Tilemap>()
.