I'm using unity, with 2D Tilemaps (I'm doing something like an RPG)
I want to have a Tile which should be rendered with a random sprite.
When I use a tile like a tree that is bigger than the tile size and RandomTile, the draw order seems to get confused. Even if the sort order on the Tilemap Renderer is set appropriately, some of the tiles are drawing on top of the other tiles with no consistent pattern.
After stepping through with the Frame Debugger, it looks like all tiles with the same sprite are drawn at the same Draw Dynamic event under TilemapRenderer.Render.
I'm using the following script:
using System;
using System.Collections;
using System.Collections.Generic;
#if UNITY_EDITOR
using UnityEditor;
#endif
using UnityEngine;
namespace UnityEngine.Tilemaps
{
[Serializable]
public class RandomTile : Tile
{
[SerializeField]
public Sprite[] m_Sprites;
public override void GetTileData(Vector3Int location, ITilemap tileMap, ref TileData tileData)
{
base.GetTileData(location, tileMap, ref tileData);
if ((m_Sprites != null) && (m_Sprites.Length > 0))
{
long hash = location.x;
hash = (hash + 0xabcd1234) + (hash << 15);
hash = (hash + 0x0987efab) ^ (hash >> 11);
hash ^= location.y;
hash = (hash + 0x46ac12fd) + (hash << 7);
hash = (hash + 0xbe9730af) ^ (hash << 11);
Random.InitState((int)hash);
tileData.sprite = m_Sprites[(int) (m_Sprites.Length * Random.value)];
}
}
#if UNITY_EDITOR
[MenuItem("Assets/Create/Random Tile")]
public static void CreateRandomTile()
{
string path = EditorUtility.SaveFilePanelInProject("Save Random Tile", "New Random Tile", "asset", "Save Random Tile", "Assets");
if (path == "")
return;
AssetDatabase.CreateAsset(ScriptableObject.CreateInstance<RandomTile>(), path);
}
#endif
}
#if UNITY_EDITOR
[CustomEditor(typeof(RandomTile))]
public class RandomTileEditor : Editor
{
private RandomTile tile { get { return (target as RandomTile); } }
public override void OnInspectorGUI()
{
EditorGUI.BeginChangeCheck();
int count = EditorGUILayout.DelayedIntField("Number of Sprites", tile.m_Sprites != null ? tile.m_Sprites.Length : 0);
if (count < 0)
count = 0;
if (tile.m_Sprites == null || tile.m_Sprites.Length != count)
{
Array.Resize<Sprite>(ref tile.m_Sprites, count);
}
if (count == 0)
return;
EditorGUILayout.LabelField("Place random sprites.");
EditorGUILayout.Space();
for (int i = 0; i < count; i++)
{
tile.m_Sprites[i] = (Sprite) EditorGUILayout.ObjectField("Sprite " + (i+1), tile.m_Sprites[i], typeof(Sprite), false, null);
}
if (EditorGUI.EndChangeCheck())
EditorUtility.SetDirty(tile);
}
}
#endif
}
Is there any way to fix it?