Bir Tilemap tüm fayans almak nasıl?


13

TileMapUnity'deki yeni sistemi biraz deniyorum ve bir liste veya 2B dizi olarak fayans erişmek için bir yol arıyordum ama GetTile(Vector3Int vector)sadece bir karo döndüren başka bir şey bulamıyorum ... herhangi bir yolu var mı Bunu yapmak için ?

Yanıtlar:


19

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 nulldeğ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. cellBoundsEğ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:


11

İş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);
}

2

Tilemap tüm özel fayans almak ve nedeniyle nasıl bulmaktan sırasında ITilemapdeğil sahiptir GetTilesBlockcevapları 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.


Hangi durumda ITilemap arayüzü ile uğraşmanız gerekir? Tilemap sistemi ile yaptığım deneyler sırasında hiç karşılaşmadım. Tilemap bileşenini her zaman ile satın aldım GetComponent<Tilemap>().
Philipp

~ Philipp, arayüz hakkında hiçbir şey söyleyemem, çünkü sadece Bileşen ile çalıştım.
Dmitry Tabakov
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.