如何动态设置tilemap中的tile?

时间:2019-02-26 15:31:23

标签: unity3d

我正在使用Isometric Tilemap制作游戏地图。
我使用的是Unity 2018 3.5f版本。

但是每个指南都说只使用调色板,但是我的游戏tilemap有点 动态。因此,我可以在运行时(动态)添加,更改和删除tilemap中的图块。 而且我必须从地图xml文件读取切片数据。因此,我可以通过编程方式添加图块。 参考中有一个“ setTile()”方法。但是,没有适当的示例使用此功能。 我是否应该首先创建平铺游戏对象并将其拖动到prefabs文件夹中以使其成为平铺预制件。我必须这样使用吗?

setTile(position , TilePrefab.Instantiate());

请问我如何使用setTile以编程方式添加图块的示例。 而且我是团结的新手,因此,如果您介意,请提供有关tilemap(更多内容)的更多提示或建议。

2 个答案:

答案 0 :(得分:3)

一年后,我偶然发现了这个问题,不得不对uglycoyote的答案进行调整才能使其与RuleTiles一起使用,所以我想我将发布必须做的更改,以防万一有人找到这个答案。

好消息是您还可以通过这种方式实现RuleTiles!不必创建Tile属性,而必须创建TileBase属性,就像这样:

public TileBase water;
public TileBase grass;

此外,在同一类中,创建一个Tilemap属性并将其公开,如下所示:

public Tilemap tileMap;

现在,进入检查器并将您的图块(无论是RuleTiles还是普通图块)拖到公开的图块属性中,然后将图块地图从层次结构视图中拖动到公开的tileMap属性中。这为您提供了从此类中对该tileMap对象的引用。

从这里开始,就像创建一个for循环来填充图块地图一样简单:

for(int x = 0; x < 10; x++) {
    for(int y = 0; y < 10; y++) {
        tileMap.SetTile(new Vector3Int(x, y, 0), grass);
    }
}

例如,上面的代码将创建仅包含草砖的10x10地图,但是您可以在嵌套的for循环中执行任何操作。

答案 1 :(得分:1)

这似乎根本不是一个“新手”问题。显然,您只想通过编程方式放置图块,而不是通过编辑器来放置图块。

我遇到了同样的问题,因为我想基于地形生成器填充瓷砖。令我感到惊讶的是,在这方面却缺少文档,而且那里的每个教程似乎都假设您是手工创作平铺布局。

这对我有用:

第一个代码片段没有回答您的问题,但这是我的测试代码,用于以棋盘格图案放置交替的磁贴(我只有两个磁贴,“水”和“地”)

for (int x = 0; x < 10; x++)
{
    for (int y = 0; y < 10; y++)
    {
        Vector3Int p = new Vector3Int(x,y,0);
        bool odd = (x + y) % 2 == 1;
        Tile tile = odd ? water : land;
        tilemap.SetTile(p, tile);
    }
}

为了获取Tile的实例,我发现有两种不同的方法有效:

方法1:使用编辑器将图块连接到属性

MonoBehaviour类中,您在其中编写用于以编程方式生成图块布局的代码,公开了一些公共属性:

public Tile water;
public Tile land;

然后在Unity Inspector中,将显示这些字段。如果按下这些属性旁边的小靶心,它将打开“选择图块”窗口,您应该可以在其中看到以前添加到“图块调色板”中的所有图块

方法2:以编程方式从“资源”文件夹中的“纹理”创建图块

如果您有许多不同的图块类型,则如上所述手动连接属性可能会变得乏味而烦人。

如果您想在代码中利用一些智能的图块命名方案,那么使用第二种方法可能更有意义。 (例如,也许您有水的四个变体和四个土地,分别称为water_01,water_02,water_03,water_04,land_01等,那么您可以轻松地编写一些代码以将所有纹理“ water _” + n的n从1加载到numVariants)。

这是我用来从保存为Assets/Resources/Textures/water.png的128x128纹理加载和创建图块的方法:

Tile water = new Tile();
Texture2D texture = Resources.Load<Texture2D>("Textures/water") as Texture2D;
water.sprite = Sprite.Create(texture,
    new Rect(0, 0, 128, 128), // section of texture to use
    new Vector2(0.5f, 0.5f), // pivot in centre
    128, // pixels per unity tile grid unit
    1,
    SpriteMeshType.Tight,
    Vector4.zero
);