Як отримати всі плитки з Tilemap?


13

Я трохи пробував нову TileMapсистему в Unity, і шукав спосіб отримати доступ до плиток у вигляді масиву List або 2D, але я не можу знайти нічого, крім того, GetTile(Vector3Int vector)що повертає лише одну плитку ... Чи є спосіб зробити це ?

Відповіді:


18

Щоб отримати масив із усіма плитками з прямокутної області вашої карти плиток, використовуйте tilemap.GetTilesBlock(BoundsInt bounds). У вас вийде одновимірний масив плиток, тому вам потрібно знати самі, коли починається наступний ряд плиток. Будь-які порожні комірки будуть представлені зі nullзначенням.

Якщо ви хочете всю плитку, використовуйте tilemap.cellBounds. Це дає вам BoundsIntоб'єкт, який охоплює всю використану область кавової карти. Ось приклад сценарію, який отримує всі плитки з Tilemap на одному ігровому об’єкті та перераховує плитки з їх координатами:

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)");
                }
            }
        }        
    }   
}

Що стосується меж та чому ви можете отримати більше плиток, ніж ви очікували: Концептуально Tilemaps Unity має необмежений розмір. cellBoundsРости по мірі необхідності , коли ви малюєте плитки, але вони не дають усадку знову , якщо ви видалите їх. Тож, коли у вашій грі чітко визначений розмір карти, ви можете отримати сюрпризи, якщо ви коли-небудь сповзатимете під час редагування карт. Існує три способи вирішити цю проблему:

  • Зателефонуйте, tilemap.CompressBounds()щоб відновити межі до самих плиток (сподіваючись, що ви пам’ятаєте, що стерти їх)
  • створити boundsоб’єкт самостійно, new BoundsInt(origin, size)а не покладатися на нього cellBounds.
  • встановіть tilemap.originі tilemap.sizeбажані значення, а потім зателефонуйте tilemap.ResizeBounds().

11

Ось ще один спосіб зробити це .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

Під час з'ясувати , як отримати всі призначені для користувача плитки з Tilemap і з - за ITilemapне має GetTilesBlockметод , який згадується у відповідях я пропоную , щоб додати метод розширення , як це (тільки 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();
    }
}

У цьому випадку, якщо у вас, припустимо, власна плитка TileRoad, успадкована від Tile або TileBase, ви можете отримати всі плитки TileRoad з викликом:

TileBase[] = tilemap.GetTiles<RoadTile>();

Для ITilemap ми можемо змінити параметр , (this Tilemap tilemap)щоб (this ITilemap tilemap)але я не перевіряв це.


У якій ситуації вам потрібно мати справу з інтерфейсом ITilemap? Я взагалі не стикався з цим під час своїх експериментів із системою Tilemap. Я завжди придбав компонент Tilemap з GetComponent<Tilemap>().
Філіп

~ Філіп, нічого не можу розповісти про інтерфейс, тому що я працював і з Component.
Дмитро Табаков
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.