Come ottenere tutte le tessere da una Tilemap?


13

Ho provato un po 'il nuovo TileMapsistema in Unity e stavo cercando un modo per accedere ai riquadri come elenco o array 2D ma non riesco a trovare altro GetTile(Vector3Int vector)che restituire solo un riquadro ... Esiste un modo per farlo ?

Risposte:


18

Per ottenere una matrice con tutte le tessere da un'area rettangolare della piastrella, utilizzare tilemap.GetTilesBlock(BoundsInt bounds). Otterrai una matrice unidimensionale di tessere, quindi devi sapere da solo quando inizia la prossima fila di tessere. Qualsiasi cella vuota verrà rappresentata con un nullvalore.

Se vuoi tutte le tessere, usa tilemap.cellBounds. Questo ti BoundsIntdà un oggetto che copre l'intera area utilizzata della tilemap. Ecco uno script di esempio che ottiene tutte le tessere dalla Tilemap sullo stesso oggetto di gioco ed elenca le tessere con le loro coordinate:

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

Per quanto riguarda i limiti e il motivo per cui potresti ottenere più riquadri di quanto ti aspetti: concettualmente, le tessere Unity hanno dimensioni illimitate. Il cellBoundscrescere come necessario quando si dipinge piastrelle, ma non ridursi ancora se li si cancella. Quindi, quando il tuo gioco ha una dimensione della mappa ben definita, potresti avere delle sorprese se scivoli durante la modifica delle mappe. Esistono tre modi per aggirare questo problema:


11

Ecco un altro modo per farlo .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

Durante la ricerca di come ottenere tutte le tessere personalizzate da Tilemap e a causa del metodo ITilemapnon GetTilesBlockindicato nelle risposte, suggerisco di aggiungere un metodo di estensione come questo (solo 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();
    }
}

In questo caso, se hai, supponi, tessere personalizzate TileRoad, ereditate da Tile o TileBase, puoi ottenere tutte le tessere TileRoad con la chiamata:

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

Per ITilemap possiamo cambiare il parametro (this Tilemap tilemap)in (this ITilemap tilemap)ma non l'ho verificato.


In quale situazione è necessario gestire l'interfaccia ITilemap? Non l'ho mai incontrato durante i miei esperimenti con il sistema Tilemap. Ho sempre acquisito il componente Tilemap con GetComponent<Tilemap>().
Philipp,

~ Philipp, non posso dire nulla sull'interfaccia, perché ho lavorato solo con Component.
Dmitry Tabakov il
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.