Answers:
要从图块贴图的矩形区域获取包含所有图块的数组,请使用tilemap.GetTilesBlock(BoundsInt bounds)
。您将获得一维拼贴块,因此您需要自己知道下一排拼贴块何时开始。任何空单元格都将用一个null
值表示。
如果需要所有图块,请使用tilemap.cellBounds
。这将为您提供一个BoundsInt
覆盖tilemap完整使用区域的对象。这是一个示例脚本,该脚本从同一个游戏对象上的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 Tilemap具有无限大小。在cellBounds
需要的时候你画砖,但如果你删除他们,他们不要再缩水增长。因此,当您的游戏具有明确定义的地图尺寸时,如果您在编辑地图时滑倒,可能会有些意外。有三种方法可以解决此问题:
tilemap.CompressBounds()
将边界恢复到最外面的图块(希望您记住要擦除它们)bounds
自己创建对象new BoundsInt(origin, size)
而不是依赖cellBounds
。tilemap.origin
和设置tilemap.size
为所需的值,然后调用tilemap.ResizeBounds()
。这是另一种方法 .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);
}
在弄清楚如何从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 tile:
TileBase[] = tilemap.GetTiles<RoadTile>();
对于ITilemap,我们可以将参数更改(this Tilemap tilemap)
为,(this ITilemap tilemap)
但是我没有检查。
GetComponent<Tilemap>()
。