/// <summary> /// Parse Tiled .tsx files to get the correct values from the fields and attributes. /// </summary> private void ParseTilesetFiles() { this.tilesets = new List <TilesetData>(); var tilesetsInfo = tilemapJsonInfo.tilesets; int tilesetCount = tilesetsInfo.Length; // Create assets for each tileset int i = 0; foreach (Tileset tileset in tilesetsInfo) { string tilesetSource = tileset.source; string absoluteTilesetSource = FromAbsolutePath(tilesetSource); TilesetInfo tilesetInfo = ParseFile(absoluteTilesetSource); string tilesetName = tilesetInfo.name; // Get the full path for the tileset ScriptableObject asset string tilesetAssetFilePath = GetAssetPath(TILESETS_PATH, tilesetName); string layerName = tilemapJsonInfo.layers[i].name; // Check if tileset exists bool tilesetAssetExists = TilesetDataExists(tilesetAssetFilePath); Debug.LogFormat($"{tilesetAssetFilePath} exists = {tilesetAssetExists}"); // Add existing assets if they don't exist and don't need to be overwritten if (tilesetAssetExists && !overwriteTilesetAssets) { AddExistingTilesetDataAsset(tilesetAssetFilePath); } else { string sheetPath = FromAbsolutePath(tilesetInfo.image); // If re-slicing sheet, get dimensions via the tileset.json if (overwriteSpritesheetSlice) { SliceSprite(sheetPath, tilesetInfo.tilewidth, tilesetInfo.tileheight); } #if DEBUG Debug.LogFormat("sheetPath [{0}]", sheetPath); #endif TilesetData asset = ScriptableObject.CreateInstance <TilesetData>(); asset.name = layerName; asset.firstGid = tileset.firstgid; // Only overwrite lastGid if more than one tileset. Else default of int.MAX if (tilesetCount > i + 1) { asset.lastGid = tilesetsInfo[i + 1].firstgid - 1; } ProcessSpritesFromSheet(tilesetName, sheetPath, asset); } i++; } }
/// <summary> /// Create Tile assets for a given tileset /// </summary> /// <param name="asset"></param> /// <param name="sprite"></param> private void CreateTilesetAssets(TilesetData asset, Sprite sprite) { string tilename = sprite.name; Tile tile = CreateTileAssets(sprite); SaveAssetToDatabase(tile, path, tilename); #if DEBUG Debug.LogFormat("NEW SPRITE [{0}]", newTile); #endif asset.tilePrefabs.Add(tile); }
/// <summary> /// Gets the proper TilesetData based off the tiled tileIndex. The tileIndex gets the TilesetData if it fits /// into the right "bucket" of gid values. /// </summary> /// <param name="tileIndex"></param> /// <returns></returns> private TilesetData GetTilesetDataFromIndex(int tileIndex) { TilesetData res = null; foreach (TilesetData tileset in tilesets) { int first = tileset.firstGid; int last = tileset.lastGid; if (first <= tileIndex && tileIndex <= last) { res = tileset; break; } } return(res); }
/// <summary> /// Process sprites from a .png spritesheet. Spritesheet isn't automatically split and must be done /// manually beforehand. /// </summary> /// <param name="tilesetName"></param> /// <param name="filename"></param> /// <param name="asset"></param> private void ProcessSpritesFromSheet(string tilesetName, string filename, TilesetData asset) { var sprites = AssetDatabase.LoadAllAssetsAtPath(filename) .OfType <Sprite>() .ToArray(); // Sort the order of sprites as they may be out of order Array.Sort(sprites, (o1, o2) => { var s1 = o1.name.Split('_'); var s2 = o2.name.Split('_'); string n1 = s1[s1.Length - 1]; string n2 = s2[s2.Length - 1]; return(int.Parse(n1) - int.Parse(n2)); }); foreach (Sprite sprite in sprites) { CreateTilesetAssets(asset, sprite); } tilesets.Add(asset); SaveAssetToDatabase(asset, TILESETS_PATH, tilesetName); }
/// <summary> /// Adds this tileset asset into the list for import /// </summary> /// <param name="filePath"></param> private void AddExistingTilesetDataAsset(string filePath) { TilesetData tilesetAsset = AssetDatabase.LoadAssetAtPath <TilesetData>(filePath); tilesets.Add(tilesetAsset); }
/// <summary> /// Process a Layer from the whole tilemap /// </summary> /// <param name="layer"></param> /// <exception cref="ArgumentOutOfRangeException"></exception> private void ProcessLayer(Layer layer) { string layerName = layer.name; int id = layer.id; int totalHeight = layer.height; int totalWidth = layer.width; int startX = layer.startx; int startY = layer.starty; int layerX = layer.x; int layerY = layer.y; IDictionary <string, TiledImporterProperty> propertiesByKey = layer.properties.PropertiesEnumerableToDictionary(); Tilemap tilemap = NewTilemap(layerName, layerX, layerY, propertiesByKey); // Get var chunks = layer.chunks; foreach (Chunk chunk in chunks) { int[] data = chunk.data; int chunkStartX = chunk.x; int chunkStartY = chunk.y; int height = chunk.height; int width = chunk.width; int x = chunkStartX; int y; switch (renderOrder) { case RenderOrder.RIGHT_DOWN: case RenderOrder.LEFT_DOWN: y = -chunkStartY; break; case RenderOrder.RIGHT_UP: case RenderOrder.LEFT_UP: y = chunkStartY; break; default: throw new ArgumentOutOfRangeException(); } #if DEBUG Debug.Log($"CHUNK START [({x}, {y})]"); #endif foreach (int tileIndex in data) { if (tileIndex > 0) { TilesetData tilesetData = GetTilesetDataFromIndex(tileIndex); int offset = tilesetData.firstGid; int index = tileIndex - offset; #if DEBUG Debug.Log($"CHUNK [{tileIndex}, {index}, {offset}, ({x}, {y})]"); #endif Tile tile = tilesetData.tilePrefabs[index]; Vector3Int pos = new Vector3Int(x, y, 0); tilemap.SetTile(pos, tile); } bool validCoordinates; (x, y, validCoordinates) = AdvanceOffsets(x, y, width, chunkStartX); if (!validCoordinates) { break; } } } }