Yanıtlar:
Tilemap'inizin dikdörtgen bir alanından tüm döşemeleri içeren bir dizi almak için kullanın tilemap.GetTilesBlock(BoundsInt bounds)
. Tek boyutlu bir karo dizisi elde edersiniz, bu nedenle bir sonraki karo satırının ne zaman başladığını kendiniz bilmeniz gerekir. Boş hücreler bir null
değerle temsil edilir .
Tüm karoları istiyorsanız , kullanın tilemap.cellBounds
. Bu BoundsInt
, tilemap'in tüm kullanım alanını kapsayan bir nesne sağlar. İşte aynı oyun nesnesindeki Tilemap'tan tüm karoları alan ve karoları koordinatlarıyla listeleyen örnek bir komut dosyası:
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)");
}
}
}
}
}
Sınırlar ve neden beklediğinizden daha fazla karo alabileceğiniz konusunda: Kavramsal olarak Unity Tilemaps'in sınırsız boyutu vardır. cellBounds
Eğer fayans boyarken gerekli, ancak bunları silerseniz tekrar küçültmek yok olarak artış. Dolayısıyla, oyununuz iyi tanımlanmış bir harita boyutuna sahip olduğunda, haritaları düzenlerken kayırsanız bazı sürprizler yaşayabilirsiniz. Bu soruna geçici bir çözüm bulmak için üç yol vardır:
tilemap.CompressBounds()
Sınırları en dıştaki döşemelere geri yüklemek için arayın (onları silmeyi hatırladığınızı umarak)bounds
nesneyi kendiniz oluşturun .new BoundsInt(origin, size)
cellBounds
tilemap.origin
ve tilemap.size
istenen değerler ve ardından çağrısına tilemap.ResizeBounds()
.İşte bunu yapmanın başka bir yolu .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);
}
Tilemap tüm özel fayans almak ve nedeniyle nasıl bulmaktan sırasında ITilemap
değil sahiptir GetTilesBlock
cevapları belirtilen yöntem böyle bir uzantısı yöntemi eklemek için önermek (2B için):
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();
}
}
Bu durumda, Tile veya TileBase'den devralınan özel döşeme TileRoad'ınız varsa, tüm TileRoad döşemelerini çağrı ile alabilirsiniz:
TileBase[] = tilemap.GetTiles<RoadTile>();
ITilemap için parametreyi (this Tilemap tilemap)
olarak değiştirebiliriz (this ITilemap tilemap)
ama bunu kontrol etmedim.
GetComponent<Tilemap>()
.