¿Cómo obtener todos los mosaicos de un Tilemap?

13

He estado probando un poco el nuevo TileMapsistema en Unity y estaba buscando una forma de acceder a los mosaicos como una Lista o matriz 2D, pero no puedo encontrar otra cosa que no sea GetTile(Vector3Int vector)que solo devuelva un mosaico ... ¿Hay alguna manera? para hacer esto ?

Shashimee
fuente

Respuestas:

18

Para obtener una matriz con todos los mosaicos de un área rectangular de su mosaico, use tilemap.GetTilesBlock(BoundsInt bounds). Obtendrá una matriz unidimensional de mosaicos, por lo que debe saber por sí mismo cuándo comienza la siguiente fila de mosaicos. Cualquier celda vacía se representará con un nullvalor.

Si quieres todas las fichas, úsalas tilemap.cellBounds. Esto le proporciona un BoundsIntobjeto que cubre el área completa utilizada del mosaico. Aquí hay un script de ejemplo que obtiene todos los mosaicos del mapa de mosaicos en el mismo objeto del juego y enumera los mosaicos con sus coordenadas:

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

Con respecto a los límites y por qué podría obtener más fichas de lo que espera: Conceptualmente, los mapas de fichas de Unity tienen un tamaño ilimitado. El cellBoundscultivo, según sea necesario cuando pintas azulejos, pero no se contraen de nuevo si los borre. Entonces, cuando su juego tiene un tamaño de mapa bien definido, puede obtener algunas sorpresas si alguna vez se resbala mientras edita mapas. Hay tres formas de solucionar este problema:

Philipp
fuente
11

Aquí hay otra forma de hacerlo con .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);
}
codificado
fuente
2

Al descubrir cómo obtener todos los mosaicos personalizados de Tilemap y debido al método de ITilemapno haber GetTilesBlockmencionado en las respuestas, sugiero agregar un método de extensión como este (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();
    }
}

En este caso, si tiene, supongamos, un mosaico personalizado TileRoad, heredado de Tile o TileBase, entonces puede obtener todos los mosaicos de TileRoad con llamada:

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

Para ITilemap podemos cambiar el parámetro (this Tilemap tilemap)a (this ITilemap tilemap)pero no lo comprobé .

Dmitry Tabakov
fuente
¿En qué situación necesita lidiar con la interfaz ITilemap? No lo encontré en absoluto durante mis experimentos con el sistema Tilemap. Siempre adquirí el componente Tilemap con GetComponent<Tilemap>().
Philipp
~ Philipp, no puedo decir nada sobre la interfaz, porque también trabajé con Component.
Dmitry Tabakov