Câu trả lời:
Để có được một mảng với tất cả các ô từ một khu vực hình chữ nhật của tilemap của bạn, hãy sử dụng tilemap.GetTilesBlock(BoundsInt bounds)
. Bạn sẽ nhận được một mảng gạch một chiều, vì vậy bạn cần phải tự biết khi hàng gạch tiếp theo bắt đầu. Bất kỳ ô trống sẽ được đại diện với một null
giá trị.
Nếu bạn muốn tất cả gạch, sử dụng tilemap.cellBounds
. Điều này giúp bạn có một BoundsInt
đối tượng bao gồm toàn bộ khu vực được sử dụng của tilemap. Dưới đây là tập lệnh ví dụ lấy tất cả các ô từ Tilemap trên cùng một đối tượng trò chơi và liệt kê các ô có tọa độ của chúng:
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)");
}
}
}
}
}
Về giới hạn và lý do tại sao bạn có thể nhận được nhiều gạch hơn bạn mong đợi: Về mặt khái niệm, Unity Tilemaps có kích thước không giới hạn. Sự cellBounds
phát triển khi cần thiết khi bạn sơn gạch, nhưng chúng sẽ không co lại nếu bạn xóa chúng. Vì vậy, khi trò chơi của bạn có kích thước bản đồ được xác định rõ, bạn có thể gặp một số bất ngờ nếu bạn trượt trong khi chỉnh sửa bản đồ. Có ba cách để giải quyết vấn đề này:
tilemap.CompressBounds()
để khôi phục giới hạn cho các ô ngoài cùng (hy vọng bạn nhớ xóa chúng)bounds
đối tượng new BoundsInt(origin, size)
thay vì dựa vào cellBounds
.tilemap.origin
và tilemap.size
đến các giá trị mong muốn và sau đó gọi tilemap.ResizeBounds()
.Đây là một cách khác để làm điều đó với .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);
}
Trong quá trình tìm hiểu làm thế nào để có được tất cả các ô tùy chỉnh từ Tilemap và do phương pháp ITilemap
chưa GetTilesBlock
được đề cập trong câu trả lời, tôi đề nghị thêm một phương thức mở rộng như thế này (chỉ 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();
}
}
Trong trường hợp này, nếu bạn có, giả sử, lát gạch tùy chỉnh, được kế thừa từ Ngói hoặc Ngói, thì bạn có thể nhận được tất cả các ô Xếp gạch với cuộc gọi:
TileBase[] = tilemap.GetTiles<RoadTile>();
Đối với ITilemap chúng ta có thể thay đổi thông số (this Tilemap tilemap)
để (this ITilemap tilemap)
nhưng tôi đã không kiểm tra đó.
GetComponent<Tilemap>()
.