Làm cách nào để có được tất cả các ô từ Tilemap?


13

Tôi đã thử một chút TileMaphệ thống mới trong Unity và tôi đang tìm cách truy cập các ô dưới dạng mảng Danh sách hoặc 2D nhưng tôi không thể tìm thấy bất cứ thứ gì ngoài GetTile(Vector3Int vector)việc chỉ trả về một ô ... Có cách nào không để làm điều này ?

Câu trả lời:


18

Để 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 nullgiá 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ự cellBoundsphá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:


11

Đâ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);
}

2

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 ITilemapchư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 đó.


Trong tình huống nào bạn cần để đối phó với giao diện ITilemap? Tôi hoàn toàn không gặp phải nó trong các thử nghiệm với hệ thống Tilemap. Tôi luôn có được thành phần Tilemap với GetComponent<Tilemap>().
Philipp

~ Philipp, không thể nói bất cứ điều gì về giao diện, vì tôi cũng chỉ làm việc với Thành phần.
Dmitry Tabakov
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.