首页 > 解决方案 > 每个 Tilemap Tile 数据存储和检索

问题描述

我有一个场景,我需要知道有关瓷砖地图中所有瓷砖的某些信息。从我所做的研究和其他人的问题来看,这可能不是最容易做的事情。

据我所知,我面临 3 种可能的选择:

  1. 不要使用 Unity 的 Tilemap,而是通过 GameObjects 和 sprite 列表手动构建图块。然后将我可能需要的任何类型的模型与自定义值作为脚本附加到所述 GO。这将使向每个图块添加逻辑变得非常简单。缺点是构建地图会更烦人。

  2. 使用 Unity 的 Tilemap,但手动跟踪代码中的每个特殊节点图块。不用说,这不是一个非常有吸引力的工作流程,因为任何时候地图发生变化,变化都需要反映在代码地图/列表/数组中

  3. 覆盖 Unity 的瓷砖(就像 2d 附加包一样)并为每个特殊瓷砖创建一个规则瓷砖。在阅读瓷砖并编译字典时,检查瓷砖的类型并根据您当前正在查看的瓷砖类型分配任何特殊属性。规则图块可以是可视图块,也可以绘制在可视图块图下方的图块图上,仅用于存储其上方地图的信息。

  4. (3.1) 与上述相同,但不使用特殊规则图块,而是将任何特殊图块分离到它们自己的特殊图块地图上。然后通读每个图块地图并编译一个字典,记录任何特殊图块及其特殊属性。

目前我正在使用以下内容:

private void GetWorldTiles ()   { 
    tiles = new Dictionary<Vector3, WorldTile>();       
    foreach (Vector3Int pos in Tilemap.cellBounds.allPositionsWithin)       {
        var localPlace = new Vector3Int(pos.x, pos.y, pos.z); 
        if (!Tilemap.HasTile(localPlace)) continue;
        var tile = new WorldTile
        {   
            LocalPlace = localPlace,
            WorldLocation = Tilemap.CellToWorld(localPlace),
            TileBase = Tilemap.GetTile(localPlace),
            TilemapMember = Tilemap,
            Name = localPlace.x + "," + localPlace.y,
            Cost = 1 // Cost is needed for pathfinding. Other properties may also exist such as "isSpawnPoint", or what have you.
        };                      
        tiles.Add(tile.WorldLocation, tile); //tiles is a Dictionary<string, WorldTile>
    }
}

上面的代码是从这个简短的教程中提取

我的地图内容将是半随机的。例如,玩家角色将在每张地图上都有专用的生成点,但敌方角色将随机生成在允许他们生成的任何图块上。一些图块还会生成宝箱之类的东西,而其他图块将具有特殊属性,例如水图块只能被水单位穿过等。

目前,这是一张简单地图的样子,所有精灵都作为占位符。简单来说,六角图块是障碍物,X块图块也是无法通过的墙,显示出地图的边界(最终产品地图大小可能会有所不同)

简单示例 Tilemap

游戏将使用广度优先搜索算法来允许战术风格的回合制移动,所以我知道哪些瓷砖会因某种原因成为障碍是至关重要的。

如果您有任何问题,我很乐意为您解答。

附加信息

我还看到 Tiles 引用了一个 gameObject 属性,但我还没有看到任何使用这个的例子。

标签: unity3d

解决方案


你可以在你的瓦片地图中为每种类型的基础地形设置一个图层,并为每个地形图层附加一个脚本,指定允许哪些类型的单位进入属于该图层的瓦片。一些空间可能有重叠的瓦片层。例如,山脉可能有一个“土地”板块和一个“山”板块。

然后,当您进行寻路计算时,您只考虑至少有一个瓦片的空间(以防止单位从地图上移开)并且允许单位类型输入该空间上的每种类型的瓦片。像这样的东西:

public class TerrainLayer : MonoBehaviour
{
    public bool canAirUnitsEnter;
    public bool canLandUnitsEnter;
    public bool canSeaUnitsEnter;
}

在此处输入图像描述

在此处输入图像描述

在此处输入图像描述

在此处输入图像描述

在此处输入图像描述


推荐阅读