Unity Tilemap开发问题:点击保留目标Tile 删除同类型其他Tile
Unity Tilemap 删除同类型Tile(除点击Tile外)解决方案
你的问题出在遍历tilebaseArray时只拿到了Tile对象,没有对应的坐标信息。直接遍历Tilemap的Bounds坐标范围就能解决这个问题,以下是修改后的完整代码和关键说明:
修改后的代码
private Grid grid; private Tilemap baseTilemap; private Tilemap overlayTilemap; private TileBase overlayTile; private BoundsInt bounds; private Vector3Int activeTileCoordinate; void Start() { grid = GetComponent<Grid>(); // 确保baseTilemap和overlayTilemap已在Inspector中赋值 bounds = new BoundsInt(baseTilemap.origin, baseTilemap.size); Debug.Log("Tile总数: " + bounds.size.x * bounds.size.y * bounds.size.z); } void Update() { Vector3 mouseWorldPos = Camera.main.ScreenToWorldPoint(Input.mousePosition); mouseWorldPos.z = 0; // 与Tilemap保持同一Z轴平面,避免坐标转换错误 activeTileCoordinate = grid.WorldToCell(mouseWorldPos); Sprite activeTileSprite = baseTilemap.GetSprite(activeTileCoordinate); if (Input.GetMouseButtonDown(0)) { try { if (activeTileSprite == null) { Debug.LogWarning("点击位置无Tile"); return; } Debug.Log("点击坐标: " + activeTileCoordinate); overlayTilemap.SetTile(activeTileCoordinate, overlayTile); // 遍历Tilemap范围内所有网格坐标 foreach (Vector3Int pos in bounds.allPositionsWithin) { // 跳过点击的Tile,不执行删除 if (pos == activeTileCoordinate) continue; TileBase tile = baseTilemap.GetTile(pos); if (tile != null && tile.name == activeTileSprite.name) { Debug.Log("删除匹配Tile: " + pos); baseTilemap.SetTile(pos, null); } } } catch (Exception e) { Debug.LogError(e); } } }
关键修改点说明
- 遍历坐标而非Tile数组:用
bounds.allPositionsWithin遍历Tilemap的所有网格坐标,每个循环直接获取当前Tile的位置pos,解决无坐标的核心问题。 - 排除点击Tile:通过
if (pos == activeTileCoordinate) continue;跳过点击的目标Tile,避免误删。 - 空值防护:添加
activeTileSprite == null判断,防止点击空白区域触发空引用错误。 - Z轴修正:鼠标转世界坐标时设置
mouseWorldPos.z = 0,确保与2D Tilemap的Z轴一致,避免坐标转换偏差。
内容的提问来源于stack exchange,提问作者KnottyDreadLox
相关产品推荐
相关产品推荐

