Skip to content

Instantly share code, notes, and snippets.

@bsimser
Created January 18, 2025 15:13
Show Gist options
  • Save bsimser/7b3b22427a35ba49e8fdfa654928554e to your computer and use it in GitHub Desktop.
Save bsimser/7b3b22427a35ba49e8fdfa654928554e to your computer and use it in GitHub Desktop.
The missing random tile from Unity's tilemap system that was removed in the most recent builds of the package
/*
This file contains the additional ETilesMenuOrder enum value for the RandomTile
Should be saved as
/Editor/Menu/MenuOrder.cs
*/
using UnityEngine;
using UnityEngine.Tilemaps;
namespace UnityEditor.Tilemaps
{
internal enum ETilesMenuItemOrder
{
RandomTile = 200
}
}
/*
This is the RandomTile from the Unity
Grab this gist and put it in your project.
Should be saved as
/Runtime/Tiles/RandomTile/RandomTile.cs
*/
using System;
#if UNITY_EDITOR
using UnityEditor;
#endif
namespace UnityEngine.Tilemaps
{
/// <summary>
/// Random Tiles are tiles which pseudo-randomly pick a sprite from a given list of sprites and a target location, and displays that sprite.
/// The Sprite displayed for the Tile is randomized based on its location and will be fixed for that particular location.
/// </summary>
[Serializable]
public class RandomTile : Tile
{
/// <summary>
/// The Sprites used for randomizing output.
/// </summary>
[SerializeField]
public Sprite[] m_Sprites;
/// <summary>
/// Retrieves any tile rendering data from the scripted tile.
/// </summary>
/// <param name="position">Position of the Tile on the Tilemap.</param>
/// <param name="tilemap">The Tilemap the tile is present on.</param>
/// <param name="tileData">Data to render the tile.</param>
public override void GetTileData(Vector3Int position, ITilemap tilemap, ref TileData tileData)
{
base.GetTileData(position, tilemap, ref tileData);
if ((m_Sprites != null) && (m_Sprites.Length > 0))
{
long hash = position.x;
hash = (hash + 0xabcd1234) + (hash << 15);
hash = (hash + 0x0987efab) ^ (hash >> 11);
hash ^= position.y;
hash = (hash + 0x46ac12fd) + (hash << 7);
hash = (hash + 0xbe9730af) ^ (hash << 11);
var oldState = Random.state;
Random.InitState((int)hash);
tileData.sprite = m_Sprites[(int) (m_Sprites.Length * Random.value)];
Random.state = oldState;
}
}
}
#if UNITY_EDITOR
[CustomEditor(typeof(RandomTile))]
public class RandomTileEditor : Editor
{
private SerializedProperty m_Color;
private SerializedProperty m_ColliderType;
private RandomTile tile { get { return (target as RandomTile); } }
/// <summary>
/// OnEnable for RandomTile.
/// </summary>
public void OnEnable()
{
m_Color = serializedObject.FindProperty("m_Color");
m_ColliderType = serializedObject.FindProperty("m_ColliderType");
}
/// <summary>
/// Draws an Inspector for the RandomTile.
/// </summary>
public override void OnInspectorGUI()
{
serializedObject.Update();
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);
}
EditorGUILayout.Space();
EditorGUILayout.PropertyField(m_Color);
EditorGUILayout.PropertyField(m_ColliderType);
if (EditorGUI.EndChangeCheck())
{
EditorUtility.SetDirty(tile);
serializedObject.ApplyModifiedProperties();
}
}
}
#endif
}
/*
This is the editor file to create the asset menu for the RandomTile
Should be saved as
/Editor/Tiles/Menu/RandomTileMenu.cs
*/
using UnityEngine;
using UnityEngine.Tilemaps;
namespace UnityEditor.Tilemaps
{
static internal partial class AssetCreation
{
[MenuItem("Assets/Create/2D/Tiles/Random Tile", priority = (int)ETilesMenuItemOrder.RandomTile)]
static void CreateRandomTile()
{
ProjectWindowUtil.CreateAsset(ScriptableObject.CreateInstance<RandomTile>(), "New Random Tile.asset");
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment