【问题标题】:How to set tile in tilemap dynamically?如何动态设置tilemap中的tile?
【发布时间】:2019-02-26 15:31:23
【问题描述】:

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

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

setTile(position , TilePrefab.Instantiate());

我可以获取一些关于如何使用 setTile 以编程方式添加图块的示例。 而且我是一个团结的新手,所以如果你介意,请提供更多关于 tilemap 的提示或建议(随便什么)。

【问题讨论】:

  • 这个问题可能有点太宽泛了,如果你所说的新手是真的。您的问题陈述是否需要有关 tilemap 或创建/实例化预制件的帮助?

标签: unity3d


【解决方案1】:

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

我遇到了同样的问题,因为我想根据地形生成器填充我的图块。令我惊讶的是,在这方面的文档如此缺乏,而且那里的每个教程似乎都假设您正在手工创作您的磁贴布局。

这对我有用:

第一个 sn-p 没有回答你的问题,但这是我的测试代码,用于以棋盘格图案放置交替的瓷砖(我只有两个瓷砖,“水”和“土地”)

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:使用编辑器将 Tiles 连接到属性

MonoBehaviour 类中,您正在编写代码以编程方式生成平铺布局,公开一些公共属性:

public Tile water;
public Tile land;

然后在 Unity Inspector 中,会出现这些字段。如果您按下这些属性旁边的小靶心,它将打开一个“选择瓷砖”窗口,您应该能够在其中看到您之前添加到瓷砖调色板中的任何瓷砖

方法 2:以编程方式从 Resources 文件夹中的 Texture 创建 Tile

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

此外,如果您想在代码中利用一些智能的磁贴命名方案,那么使用第二种方法可能更有意义。 (例如,也许您有四种水和四种土地,分别称为 water_01、water_02、water_03、water_04、land_01 等,那么您可以轻松编写一些代码来加载所有纹理 "water_"+n for n 从 1 到numVariants)。

以下是我从保存为Assets/Resources/Textures/water.png 的 128x128 纹理加载和创建 Tile 的方法:

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

【讨论】:

  • 有没有办法移除玩家看不到的图块..?
  • 我不知道 Unity 是否为此内置了任何东西。在我的例子中,我实现了一种 google-maps 风格的多级缓存和可见性系统,它只显示当前视锥体中的图块,当由于缩小而导致太多时,它会跳到更小的低分辨率图块的数量。我通过自定义 C# 代码完成了这一切。
【解决方案2】:

一年后我偶然发现了这个问题,并且不得不对丑陋狼的答案进行调整以使其与 RuleTiles 一起使用,所以我想我会发布我必须做出的更改,以防其他人找到这个答案。

好消息是您也可以通过这种方式实现 RuleTiles!我不得不创建 TileBase 属性,而不是创建 Tile 属性,如下所示:

public TileBase water;
public TileBase grass;

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

public Tilemap tileMap;

现在,进入检查器并将您的图块(无论是 RuleTiles 还是普通图块)拖到公开的图块属性中,然后将 tilemap 从层次结构视图拖到公开的 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 循环中做任何您想做的事情。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2014-10-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-01-08
    • 2018-01-06
    • 1970-01-01
    相关资源
    最近更新 更多