I'm experiencing a frustrating sorting issue with a Tilemap in Unity (Isometric layout). I have three block types: Grass, Sand, and Water.
Sprite Assets Specifications:
Dimensions: All sprites are exactly 500x500 pixels.
Pixels Per Unit (PPU): All are set to 512.
Pivot: All use an identical custom pivot of (250, 375) (which corresponds to the bottom center of the top diamond of the cube).
Geometry: The sprites are identical in shape and metadata; only the colors and filenames differ.
The Issue:
If I assign the same sprite asset (e.g., just the Grass sprite) to all three slots in my generator, the chunk renders perfectly. The $Y$-axis sorting works exactly as expected.
As soon as I use three different files (Grass.png, Sand.png, Water.png), the sorting breaks completely. Background tiles frequently render on top of foreground tiles, creating a "layer soup" effect.
using UnityEngine;
using UnityEngine.Tilemaps;
using UnityEngine.Rendering;
using System.Collections.Generic;
public class WorldGenerator : MonoBehaviour
{
[Header("Sprites")]
public Sprite waterSprite;
public Sprite sandSprite;
public Sprite grassSprite;
[Header("Settings")]
public int chunkSize = 16;
private Dictionary tileCache = new Dictionary();
void Start()
{
// Setting up global sorting for isometry
GraphicsSettings.transparencySortMode = TransparencySortMode.CustomAxis;
GraphicsSettings.transparencySortAxis = new Vector3(0, 1, -1);
GenerateSingleChunk();
}
void GenerateSingleChunk()
{
GameObject oldGrid = GameObject.Find("IsoGrid");
if (oldGrid) DestroyImmediate(oldGrid);
GameObject gridObj = new GameObject("IsoGrid");
Grid grid = gridObj.AddComponent();
grid.cellLayout = GridLayout.CellLayout.Isometric;
// Size for 500px sprites with 512 PPU
float sw = 500f / 512f;
grid.cellSize = new Vector3(sw, sw * 0.5f, 1f);
GameObject chunkObj = new GameObject("Chunk_Main");
chunkObj.transform.SetParent(gridObj.transform);
Tilemap tilemap = chunkObj.AddComponent();
TilemapRenderer tr = chunkObj.AddComponent();
tilemap.tileAnchor = Vector3.zero;
tr.mode = TilemapRenderer.Mode.Individual;
tr.sortOrder = TilemapRenderer.SortOrder.TopRight;
for (int x = 0; x < chunkSize; x++)
{
for (int y = 0; y < chunkSize; y++)
{
tilemap.SetTile(new Vector3Int(x, y, 0), GetRandomTile());
}
}
}
Tile GetRandomTile()
{
float r = Random.value;
if (r < 0.33f) return GetCachedTile("Water", waterSprite);
if (r < 0.66f) return GetCachedTile("Sand", sandSprite);
return GetCachedTile("Grass", grassSprite);
}
Tile GetCachedTile(string id, Sprite s)
{
if (!tileCache.ContainsKey(id))
{
Tile t = ScriptableObject.CreateInstance();
t.sprite = s;
tileCache[id] = t;
}
return tileCache[id];
}
}
What are the possible ways to resolve this sorting conflict?