I have a TileMap and replace tiles with scenes/sprites (coins, enemies...).

I can find the tiles like this:

var cellsWithId = tileMap.GetUsedCellsById(layer, (int)id);

Unfortunately, the ID is not always the same. I have different levels/TileMaps, and in my case, the IDs can't be used as unique identifiers. I need a way to find them by name or map the ID to the TileSet name. Is this possible?

I even didn't find the ID in the TileData that I used to search the Tiles. Do I miss something?


this reddit thread, I think it has what you are looking for, I use it and besides an error in the position (basically everything goes half a cell back, I still solve it by adding a few pixels in the positions in Y and X).

Yes, this is exactly what I'm doing. My problem is, that the TileSet ID used to identify the TileType is generated dynamically and differs for every level. I'm using the YATI tiled importer. The ID is generated while importing the tile map. Not every level has the same number of TileSets.

I need a way to Identify the TileSets from its name, image name, or something else that stays the same.

Here is my c# code for replacing tiles with scene sprites with the ID just for completeness:

	private static void ReplaceTile(PackedScene scene, int layer, TileMap tileMap, TileId id)
	{
		 var cellsWithId = tileMap.GetUsedCellsById(layer, (int)id);

		foreach (var cell in cellsWithId)
		{
			Node2D coinScene = scene.Instantiate<Node2D>();
			coinScene.Position = tileMap.MapToLocal(cell);
			tileMap.EraseCell(layer, cell);
			tileMap.AddChild(coinScene);
			GD.Print($"Scene added:  { scene } { coinScene.Position}");
		}
	}

In Godot 3 we had

find_tile_by_name

. Unfortunately, it didn't make it into version 4. I'm looking for an alternative for this.

    Maybe this helps someone else... I found a way to find the name. The ResourceName works for me. You can get it through the TileSetAtlasSource that you can access with the ID:

    				var allCells = tileMap.GetUsedCells(i);
    				foreach (var cell in allCells)
    				{
    					var id = tileMap.GetCellSourceId(i, cell);
    					var tileSetSource = (TileSetAtlasSource)tileMap.TileSet.GetSource(id);
    					GD.Print($"Name: { tileSetSource.ResourceName }");
    				}

    Some helper methods for faster and easier access to the name would be great. There are already a few GitHub issues open about that topic.

    The cast to TileSetAtlasSource was not obvious to me. I found the hint somewhere on the net.

    el_malo Thanks for the information, good to know. I'm using Tiled for the level design because my 9-year-old son makes most of the levels.
    Things break too fast when I let him create things directly in the Godot editor. He wants to paint the levels like in Ms-Paint with a simple application. Another thing is, that you can use the Tiled levels also in other game engines or even parse them by yourself. You can probably still read it in 10 years.

    I also prefer code over the editor when connecting signals and loading resources for example. It feels more robust to me. I can rename and move around things more easily in code without breaking anything.