Tilemap layers and trasparency sort axis

What I want to do:

  • Having tile based objects such as fences in the tilemap
  • The fences need to be more than 1 tile high
  • The fences need to dynamically adjust their sprite rendering order based on Y

Is the above even theoretically possible with the current Tilemaps implementation?

What I know:

  • It’s possible to use transparency sort axis to sort sprites by their Y position
  • It’s possible to have the map layer render “individual” tiles rather than “chunk”

The problems:

  • If I set the layer’s render mode to “individual” then the fence obviously doesn’t work because it’s 2 tiles high.
  • If I set the layer’s render mode to “chunk” then the baseline of the layer is always in the geometric center of the layer, instead of its lowest point, and I don’t see any way to set “sprite sort point” for a tilemap layer
  • I cannot just make a sprite out of the fence because it’s a long and potentially complicated tiled object that can greatly vary its form (I can do that with other more regular objects)

Maybe there is some obvious concept that I am missing.
Thank you in advance.

Alright here’s the solution:

  • Set the transparency axis to (0, 1, -1)
  • Manually set the Z position of the placed tiles to their “height” above the ground, for example for the fence top tile it would be Z=1

It’s … confusing… because there are 2 Z position: the grid Z position which is used for Isometric maps only (I assume, as it doesn’t change the actual tile’s sprite Z position) and then the ACTUAL Z position of the tile, which you can set in the inspector after selecting the tile.

But it works perfectly.

One other small issue is that changing the pivot of the imported sprite will make the tile palette very unreadable, but it still works like it’s supposed to in the map.

Well I’m happy that I figured this out, if anybody has any questions regarding this madness please go ahead and ask me.

Hey, encountered this same issue when I tried adding trees that are 2 tiles high.
I followed your steps but realized that it wouldn’t work if you generate a tilemap at runtime (like I am).

I found another way to fix this issue rather than manually setting the Z position for each tile.

I did it like this:

  • Set the transparency axis to (0, 1, -1)
  • Set the Grid’s Cell Size to (1, 1, 1) (instead of (1,1,0))

This allows tiles to be physically moved to the correct z position (just like you would when doing so manually).

Hope this helps others who might also encounter this issue.

2 Likes

LakeIshikawa
I’m tryin to change Z coordinate of special cell from script (basically I want to sort my sprites of trees (worldspace) with clouds which are on tileMap). I can do it manually on GridSelection, but i can’t find any solution to access position of the cell from script

If you’re just trying to sort the different sprites based on the Z axis, you should just do the solutions provided above as they do not require any extra scripts. If you do need to access your tiles from a script, check out the Tilemap scripting manual.

I need to access “cell” transform.position the way GridSelection.Select does it in the inspector, but I can’t understand what is the “cell”, and how I can change values that I can see in the inspector of GridSelection, aspecially 2nd “position”
4387630--398446--27f7fb0eb24e7ad553e4c7195e913ef8.png


I found the solution by creating scriptable tile and overriding GetTileData method.

   public Sprite m_Sprite;

   public override void GetTileData(Vector3Int location, ITilemap tilemap, ref TileData tileData)
   {
      if(HasCloudTile(tilemap, location))
      {

     
         var tempTileData = tileData.transform;
         var pos = tilemap.GetComponent<Tilemap>().GetCellCenterWorld(location);
         pos = CorrectionZHelper.GetZCorrection(pos);
         tempTileData.SetTRS(new Vector3(0f, 0f, pos.z), Quaternion.identity, Vector3.one);
         tileData.transform = tempTileData;
         tileData.sprite = m_Sprite;
      }
   }

   private bool HasCloudTile(ITilemap tilemap, Vector3Int position)
   {
      return tilemap.GetTile(position) == this;
   }