Tilemap에서 모든 타일을 얻는 방법?


13

나는 TileMapUnity 의 새로운 시스템을 조금 시험해 보았고 타일을 List 또는 2D 배열로 액세스하는 방법을 찾고 있었지만 GetTile(Vector3Int vector)타일 ​​하나만 반환하는 것 외에는 아무것도 찾을 수 없었습니다 ... 이것을하기 위해 ?

답변:


18

타일 ​​맵의 직사각형 영역에서 모든 타일이있는 배열을 얻으려면을 사용하십시오 tilemap.GetTilesBlock(BoundsInt bounds). 1 차원 배열의 타일을 얻게되므로 다음 행의 타일이 시작될 때 스스로 알아야합니다. 빈 셀은 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)");
                }
            }
        }        
    }   
}

한계와 예상보다 더 많은 타일을 얻을 수있는 이유와 관련하여 개념적으로 Unity 타일 맵은 크기가 무제한입니다. cellBounds당신이 타일을 그릴 때 필요하지만, 당신이 그들을 지울 경우 그들이 다시 축소하지 않는 한 성장. 따라서 게임의 맵 크기가 잘 정의되어 있으면 맵을 편집하는 동안 미끄러지더라도 놀라게 될 수 있습니다. 이 문제를 해결하는 세 가지 방법이 있습니다.


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

이 경우 Tile 또는 TileBase에서 상속 된 사용자 정의 Tile TileRoad가 있다고 가정하면 모든 TileRoad 타일을 호출하여 가져올 수 있습니다.

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

ITilemap의 경우 매개 변수 (this Tilemap tilemap)를로 변경할 수 (this ITilemap tilemap)있지만 확인하지 않았습니다.


어떤 상황에서 ITilemap 인터페이스를 다루어야합니까? Tilemap 시스템을 실험 할 때 전혀 발생하지 않았습니다. 나는 항상와 함께 Tilemap 구성 요소를 얻었습니다 GetComponent<Tilemap>().
Philipp

~ 필립, 구성 요소 만 사용했기 때문에 인터페이스에 대해 아무것도 말할 수 없습니다.
Dmitry Tabakov
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.