【问题标题】:Tilemap.HasTile() always returns false for the top layer of tilemap ONLYTilemap.HasTile() 总是只为 tilemap 的顶层返回 false
【发布时间】:2020-07-23 19:37:50
【问题描述】:

我正在尝试制作一款建筑游戏,您可以在其中建造任何没有建筑且接触地面的地方。这是我的代码

private void Update()
{

    if (buildMode)
    {
        playerScript.enabled = false;
        Vector3 point = Camera.main.ScreenToWorldPoint(Input.mousePosition);
        if (Input.GetMouseButtonDown(0))
        {
            buildOverlay.ClearAllTiles();
            Vector3Int selectedTile = buildOverlay.WorldToCell(point);
            selectedTile.z = 0;
            if (Vector3.Distance(GameObject.Find("Player").transform.position, selectedTile) < buildDistance)
            {
                //BoundsInt bounds = collidableTilemap.cellBounds;
                //TileBase[] allTiles = collidableTilemap.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];
                //        Debug.Log(collidableTilemap.HasTile(new Vector3Int(x, y, 0)));

                //        if (collidableTilemap.HasTile(new Vector3Int(x, y, 0)))
                //        {
                //            buildOverlay.SetTile(selectedTile, notplaceable);
                //        }
                //        else
                //        {
                //          buildOverlay.SetTile(selectedTile, placeable);

                //        }
                //    }
                //}
                selectedTile.z = 0;
                Debug.Log(selectedTile);
                Debug.Log(collidableTilemap.HasTile(selectedTile));
                if (!collidableTilemap.HasTile(selectedTile))
                {
                    buildOverlay.SetTile(selectedTile, placeable);
                }
                else
                {
                    buildOverlay.SetTile(selectedTile, notplaceable);
                }



            }




        }
        else
        {
            playerScript.enabled = true;
        }
    }
}

到目前为止,此代码所做的是关闭移动和检查重叠图块的功能。我目前将变量 buildDistance 设置为无穷大,所以这不是问题。

这里有一些图片:

Unity 认为第一层不存在。这是证明这些块在同一个tilemap中的场景视图:

此代码应该查看玩家想要放置的坐标中是否存在图块。除了第一层外,它工作正常。请帮忙!

我对 Unity 还很陌生,所以不要介意我的菜鸟错误。谢谢!

[编辑]:我稍微改变了我的地形,并意识到了一些新的东西:

这个方块是红色的

这个方块是绿色的。

我不能在这一排的任何地方建造,除了石头结束时:

我可以在这里建造:

发生了什么!!!!!!?????????

【问题讨论】:

  • 这是否也发生在地图最左边或最右边的瓦片上,或者只是顶层?你可以在地下的第一个空白线上放置一个瓷砖吗?
  • @Jake 我已根据您提出的信息更新了我的问题。怎么回事!!??!

标签: c# unity3d


【解决方案1】:

所以基本上它离 y 轴有 1 个单位,所以只需减去 1 个 y 单位。

替换这一行:

if (!collidableTilemap.HasTile(selectedTile)

if (!collidableTilemap.HasTile(selectedTile - new Vector3Int(0, 1, 0)))

这基本上会抵消 Unity 从地板对瓷砖地图的偏移效果。

【讨论】:

  • 非常感谢!这有很大帮助!我已经坚持了好几天了!
【解决方案2】:

很难确定,但似乎从世界空间到网格坐标的转换至少在 y 维度上是偏差的,我也猜想在 x 方向上。 我相信这个错误的最佳候选者是这里的这一行

Vector3Int selectedTile = buildOverlay.WorldToCell(point);

这种从floatint 的转换实际上不会将数字四舍五入,而是将其取整。 Unity 经常放置它的瓦片地图,因此瓦片与世界网格有 0.5m 的偏差,并且由于这种地板,该位置可能会导致这些问题。 我会建议尝试

Vector3Int selectedTile = buildOverlay.WorldToCell(Vector3Int.RoundToInt(point)) 

或者如果这没有帮助你可以尝试丑陋的

Vector3Int selectedTile = buildOverlay.WorldToCell(point+Vector3.one*0.5f);

(如果这仍然不起作用,您可以省略 0.5f)

不是最漂亮的解决方案,但我认为这就是你的问题所在。

【讨论】:

  • 根据此处的方向,您可能需要减去而不是添加
  • 今天会试试,你有这么多的声誉,你是一个新的贡献者,真是太疯狂了!我会告诉你它是否有效
  • @CoderDude 啊哈我刚刚问了一个非常受欢迎的问题
  • 所以我尝试了你所有的建议,它所做的只是移动瓷砖所在的位置,例如我点击的左侧和上方的一个瓷砖。关于如何移动瓷砖地图的任何想法?
猜你喜欢
  • 1970-01-01
  • 2013-12-18
  • 2022-01-26
  • 1970-01-01
  • 1970-01-01
  • 2016-07-20
  • 2021-11-05
  • 2018-11-05
  • 2019-05-06
相关资源
最近更新 更多