如何修改Unity C#代码正确加载Tiled交错等距地图为矩形
解决Tiled交错等距地图在Unity中加载显示为菱形的问题
我在Tiled中创建了交错等距(staggered)地图并导出为JSON文件,尝试用Unity的C#代码加载数据并显示为交错等距瓦片地图,但当前加载出的地图是菱形而非预期的整体矩形。
当前加载代码
using System.Collections; using System.Collections.Generic; using UnityEngine; using UnityEngine.Tilemaps; using System.IO; public class LoadMap : MonoBehaviour { public Tilemap tilemap; public Tile[] tiles; public string mapJsonPath; void Start() { string jsonText = File.ReadAllText(mapJsonPath); TiledMapData mapData = JsonUtility.FromJson<TiledMapData>(jsonText); for (int y = 0; y < mapData.height; y++) { for (int x = 0; x < mapData.width; x++) { int index = x + y * mapData.width; int tileId = mapData.layers[0].data[index] - 1; tilemap.SetTile(new Vector3Int(x, y, 0), tiles[tileId]); } } } } [System.Serializable] public class TiledMapData { public int height; public int width; public TiledMapLayer[] layers; } [System.Serializable] public class TiledMapLayer { public int[] data; }
map.json核心内容
{ "compressionlevel":-1, "height":200, "infinite":false, "layers":[ { "data":[1, 1, 1, ...], "height":200, "name":"Tile Layer 1", "width":200 }], "orientation":"staggered", "renderorder":"right-down", "staggeraxis":"y", "staggerindex":"odd", "tileheight":128, "tilewidth":256, "width":200 }
修改思路与代码调整
问题根源是Tiled交错等距坐标与Unity Tilemap坐标的转换逻辑缺失:Tiled的staggered地图中,指定行/列会有偏移,但当前代码直接使用原始(x,y)坐标设置Tilemap,导致布局错位成菱形。
步骤1:扩展TiledMapData类,读取关键参数
首先需要从JSON中读取Tiled的交错配置参数,完善数据模型:
[System.Serializable] public class TiledMapData { public int height; public int width; public string orientation; public string staggeraxis; public string staggerindex; public int tilewidth; public int tileheight; public TiledMapLayer[] layers; } [System.Serializable] public class TiledMapLayer { public int[] data; }
步骤2:添加坐标转换逻辑,修正Tile位置
修改加载逻辑,根据Tiled的交错参数计算每个Tile的正确坐标:
using System.Collections; using System.Collections.Generic; using UnityEngine; using UnityEngine.Tilemaps; using System.IO; public class LoadMap : MonoBehaviour { public Tilemap tilemap; public Tile[] tiles; public string mapJsonPath; void Start() { string jsonText = File.ReadAllText(mapJsonPath); TiledMapData mapData = JsonUtility.FromJson<TiledMapData>(jsonText); bool isOddStagger = mapData.staggerindex == "odd"; bool staggerYAxis = mapData.staggeraxis == "y"; for (int y = 0; y < mapData.height; y++) { for (int x = 0; x < mapData.width; x++) { int index = x + y * mapData.width; int tileId = mapData.layers[0].data[index] - 1; if (tileId < 0) continue; // 跳过空瓦片 Vector3Int tilePos = GetStaggeredTilePosition(x, y, staggerYAxis, isOddStagger); tilemap.SetTile(tilePos, tiles[tileId]); } } // 压缩Tilemap边界,优化显示 tilemap.CompressBounds(); } private Vector3Int GetStaggeredTilePosition(int x, int y, bool staggerYAxis, bool isOddStagger) { int offset = 0; if (staggerYAxis) { // 沿Y轴交错:奇数行(对应staggerindex=odd)添加X偏移 bool needsOffset = isOddStagger ? (y % 2 == 1) : (y % 2 == 0); offset = needsOffset ? 1 : 0; // 用x*2+offset让瓦片在X轴上错开,保证整体布局为矩形 return new Vector3Int(x * 2 + offset, -y, 0); } else { // 沿X轴交错的兼容处理(如果需要) bool needsOffset = isOddStagger ? (x % 2 == 1) : (x % 2 == 0); offset = needsOffset ? 1 : 0; return new Vector3Int(x, -y * 2 + offset, 0); } } }
额外注意事项
- 确保Unity Tilemap的Tile Anchor设置为
(0.5, 0.5),保证瓦片对齐正确。 - 检查Tile的Sprite是否为标准交错等距样式,避免因资源本身导致的布局问题。
内容的提问来源于stack exchange,提问作者Nick785
相关产品推荐
相关产品推荐

