Initial Commit

This commit is contained in:
Simeon Radivoev 2022-02-12 12:53:50 +02:00
commit ee5c2f922d
Signed by: simeonradivoev
GPG key ID: 7611A451D2A5D37A
2255 changed files with 547750 additions and 0 deletions

View file

@ -0,0 +1,10 @@
fileFormatVersion: 2
guid: 33e8a22612607064dbfaa9d21d1836e8
folderAsset: yes
timeCreated: 1499149327
licenseType: Pro
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View file

@ -0,0 +1,10 @@
fileFormatVersion: 2
guid: d8f0a7d912b6f424aa0e09f8597dd2df
folderAsset: yes
timeCreated: 1499149343
licenseType: Pro
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View file

@ -0,0 +1,126 @@
using System;
#if UNITY_EDITOR
using UnityEditor;
#endif
namespace UnityEngine.Tilemaps
{
[Serializable]
public class AnimatedTile : TileBase
{
public Sprite[] m_AnimatedSprites;
public float m_AnimationStartTime;
public float m_MaxSpeed = 1f;
public float m_MinSpeed = 1f;
public Tile.ColliderType m_TileColliderType;
public override void GetTileData(Vector3Int location, ITilemap tileMap, ref TileData tileData)
{
tileData.transform = Matrix4x4.identity;
tileData.color = Color.white;
if (m_AnimatedSprites != null && m_AnimatedSprites.Length > 0)
{
tileData.sprite = m_AnimatedSprites[m_AnimatedSprites.Length - 1];
tileData.colliderType = m_TileColliderType;
}
}
public override bool GetTileAnimationData(Vector3Int location, ITilemap tileMap, ref TileAnimationData tileAnimationData)
{
if (m_AnimatedSprites.Length > 0)
{
tileAnimationData.animatedSprites = m_AnimatedSprites;
tileAnimationData.animationSpeed = Random.Range(m_MinSpeed, m_MaxSpeed);
tileAnimationData.animationStartTime = m_AnimationStartTime;
return true;
}
return false;
}
#if UNITY_EDITOR
[MenuItem("Assets/Create/Animated Tile")]
public static void CreateAnimatedTile()
{
var path = EditorUtility.SaveFilePanelInProject("Save Animated Tile", "New Animated Tile", "asset", "Save Animated Tile", "Assets");
if (path == "")
{
return;
}
AssetDatabase.CreateAsset(CreateInstance<AnimatedTile>(), path);
}
#endif
}
#if UNITY_EDITOR
[CustomEditor(typeof(AnimatedTile))]
public class AnimatedTileEditor : Editor
{
private AnimatedTile tile => target as AnimatedTile;
public override void OnInspectorGUI()
{
EditorGUI.BeginChangeCheck();
var count = EditorGUILayout.DelayedIntField(
"Number of Animated Sprites",
tile.m_AnimatedSprites != null ? tile.m_AnimatedSprites.Length : 0);
if (count < 0)
{
count = 0;
}
if (tile.m_AnimatedSprites == null || tile.m_AnimatedSprites.Length != count)
{
Array.Resize(ref tile.m_AnimatedSprites, count);
}
if (count == 0)
{
return;
}
EditorGUILayout.LabelField("Place sprites shown based on the order of animation.");
EditorGUILayout.Space();
for (var i = 0; i < count; i++)
{
tile.m_AnimatedSprites[i] = (Sprite)EditorGUILayout.ObjectField(
"Sprite " + (i + 1),
tile.m_AnimatedSprites[i],
typeof(Sprite),
false,
null);
}
var minSpeed = EditorGUILayout.FloatField("Minimum Speed", tile.m_MinSpeed);
var maxSpeed = EditorGUILayout.FloatField("Maximum Speed", tile.m_MaxSpeed);
if (minSpeed < 0.0f)
{
minSpeed = 0.0f;
}
if (maxSpeed < 0.0f)
{
maxSpeed = 0.0f;
}
if (maxSpeed < minSpeed)
{
maxSpeed = minSpeed;
}
tile.m_MinSpeed = minSpeed;
tile.m_MaxSpeed = maxSpeed;
tile.m_AnimationStartTime = EditorGUILayout.FloatField("Start Time", tile.m_AnimationStartTime);
tile.m_TileColliderType = (Tile.ColliderType)EditorGUILayout.EnumPopup("Collider Type", tile.m_TileColliderType);
if (EditorGUI.EndChangeCheck())
{
EditorUtility.SetDirty(tile);
}
}
}
#endif
}

View file

@ -0,0 +1,12 @@
fileFormatVersion: 2
guid: 13b75c95f34a00d4e8c04f76b73312e6
timeCreated: 1464531813
licenseType: Pro
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View file

@ -0,0 +1,10 @@
fileFormatVersion: 2
guid: af0bc89550613a14fa0feadd363358e6
folderAsset: yes
timeCreated: 1499149527
licenseType: Pro
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View file

@ -0,0 +1,10 @@
fileFormatVersion: 2
guid: 64fa95bf1baeb5f4497bd5048a284208
folderAsset: yes
timeCreated: 1499146919
licenseType: Pro
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View file

@ -0,0 +1,158 @@
using System;
#if UNITY_EDITOR
using UnityEditor;
#endif
namespace UnityEngine.Tilemaps
{
[Serializable]
public class PipelineTile : TileBase
{
[SerializeField] public Sprite[] m_Sprites;
public override void RefreshTile(Vector3Int location, ITilemap tileMap)
{
for (var yd = -1; yd <= 1; yd++)
for (var xd = -1; xd <= 1; xd++)
{
var position = new Vector3Int(location.x + xd, location.y + yd, location.z);
if (TileValue(tileMap, position))
{
tileMap.RefreshTile(position);
}
}
}
public override void GetTileData(Vector3Int location, ITilemap tileMap, ref TileData tileData)
{
UpdateTile(location, tileMap, ref tileData);
}
private void UpdateTile(Vector3Int location, ITilemap tileMap, ref TileData tileData)
{
tileData.transform = Matrix4x4.identity;
tileData.color = Color.white;
var mask = TileValue(tileMap, location + new Vector3Int(0, 1, 0)) ? 1 : 0;
mask += TileValue(tileMap, location + new Vector3Int(1, 0, 0)) ? 2 : 0;
mask += TileValue(tileMap, location + new Vector3Int(0, -1, 0)) ? 4 : 0;
mask += TileValue(tileMap, location + new Vector3Int(-1, 0, 0)) ? 8 : 0;
var index = GetIndex((byte)mask);
if (index >= 0 && index < m_Sprites.Length && TileValue(tileMap, location))
{
tileData.sprite = m_Sprites[index];
tileData.transform = GetTransform((byte)mask);
tileData.flags = TileFlags.LockTransform | TileFlags.LockColor;
tileData.colliderType = Tile.ColliderType.Sprite;
}
}
private bool TileValue(ITilemap tileMap, Vector3Int position)
{
var tile = tileMap.GetTile(position);
return tile != null && tile == this;
}
private int GetIndex(byte mask)
{
switch (mask)
{
case 0: return 0;
case 3:
case 6:
case 9:
case 12: return 1;
case 1:
case 2:
case 4:
case 5:
case 10:
case 8: return 2;
case 7:
case 11:
case 13:
case 14: return 3;
case 15: return 4;
}
return -1;
}
private Matrix4x4 GetTransform(byte mask)
{
switch (mask)
{
case 9:
case 10:
case 7:
case 2:
case 8:
return Matrix4x4.TRS(Vector3.zero, Quaternion.Euler(0f, 0f, -90f), Vector3.one);
case 3:
case 14:
return Matrix4x4.TRS(Vector3.zero, Quaternion.Euler(0f, 0f, -180f), Vector3.one);
case 6:
case 13:
return Matrix4x4.TRS(Vector3.zero, Quaternion.Euler(0f, 0f, -270f), Vector3.one);
}
return Matrix4x4.identity;
}
#if UNITY_EDITOR
[MenuItem("Assets/Create/Pipeline Tile")]
public static void CreatePipelineTile()
{
var path = EditorUtility.SaveFilePanelInProject("Save Pipeline Tile", "New Pipeline Tile", "asset", "Save Pipeline Tile", "Assets");
if (path == "")
{
return;
}
AssetDatabase.CreateAsset(CreateInstance<PipelineTile>(), path);
}
#endif
}
#if UNITY_EDITOR
[CustomEditor(typeof(PipelineTile))]
public class PipelineTileEditor : Editor
{
private PipelineTile tile => target as PipelineTile;
public void OnEnable()
{
if (tile.m_Sprites == null || tile.m_Sprites.Length != 5)
{
tile.m_Sprites = new Sprite[5];
}
}
public override void OnInspectorGUI()
{
EditorGUILayout.LabelField("Place sprites shown based on the number of tiles bordering it.");
EditorGUILayout.Space();
EditorGUI.BeginChangeCheck();
tile.m_Sprites[0] = (Sprite)EditorGUILayout.ObjectField("None", tile.m_Sprites[0], typeof(Sprite), false, null);
tile.m_Sprites[2] = (Sprite)EditorGUILayout.ObjectField("One", tile.m_Sprites[2], typeof(Sprite), false, null);
tile.m_Sprites[1] = (Sprite)EditorGUILayout.ObjectField("Two", tile.m_Sprites[1], typeof(Sprite), false, null);
tile.m_Sprites[3] = (Sprite)EditorGUILayout.ObjectField("Three", tile.m_Sprites[3], typeof(Sprite), false, null);
tile.m_Sprites[4] = (Sprite)EditorGUILayout.ObjectField("Four", tile.m_Sprites[4], typeof(Sprite), false, null);
if (EditorGUI.EndChangeCheck())
{
EditorUtility.SetDirty(tile);
}
}
}
#endif
}

View file

@ -0,0 +1,12 @@
fileFormatVersion: 2
guid: 25192638efa881c469b1ac4d8cfd3f1b
timeCreated: 1464534747
licenseType: Pro
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View file

@ -0,0 +1,10 @@
fileFormatVersion: 2
guid: 47f5287a949e1094191c733949de285a
folderAsset: yes
timeCreated: 1499150037
licenseType: Pro
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View file

@ -0,0 +1,10 @@
fileFormatVersion: 2
guid: 0c3034e66d810604680654a1e667fde0
folderAsset: yes
timeCreated: 1499150048
licenseType: Pro
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View file

@ -0,0 +1,84 @@
using System;
#if UNITY_EDITOR
using UnityEditor;
#endif
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()
{
var path = EditorUtility.SaveFilePanelInProject("Save Random Tile", "New Random Tile", "asset", "Save Random Tile", "Assets");
if (path == "")
{
return;
}
AssetDatabase.CreateAsset(CreateInstance<RandomTile>(), path);
}
#endif
}
#if UNITY_EDITOR
[CustomEditor(typeof(RandomTile))]
public class RandomTileEditor : Editor
{
private RandomTile tile => target as RandomTile;
public override void OnInspectorGUI()
{
EditorGUI.BeginChangeCheck();
var 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(ref tile.m_Sprites, count);
}
if (count == 0)
{
return;
}
EditorGUILayout.LabelField("Place random sprites.");
EditorGUILayout.Space();
for (var 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
}

View file

@ -0,0 +1,12 @@
fileFormatVersion: 2
guid: 535f8e525ff367c4ba67961e201a05ed
timeCreated: 1445235751
licenseType: Pro
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View file

@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: fbcacf945e7001e4396ca2ca8573ae6c
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View file

@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 1e5614e4b96700843ba104987c4f190e
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View file

@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 1263d004036ee7f42aeed98348b5e8cf
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View file

@ -0,0 +1,350 @@
using UnityEngine;
using UnityEngine.Tilemaps;
using UnityEditor;
using UnityEditorInternal;
using System;
using System.Collections.Generic;
namespace UnityEditor
{
[CustomEditor(typeof(RuleOverrideTile))]
internal class RuleOverrideTileEditor : Editor
{
public RuleOverrideTile overrideTile { get { return (target as RuleOverrideTile); } }
private List<KeyValuePair<Sprite, Sprite>> m_Sprites;
private List<KeyValuePair<RuleTile.TilingRule, RuleTile.TilingRule>> m_Rules;
ReorderableList m_SpriteList;
ReorderableList m_RuleList;
private float k_DefaultElementHeight { get { return RuleTileEditor.k_DefaultElementHeight; } }
private float k_PaddingBetweenRules { get { return RuleTileEditor.k_PaddingBetweenRules; } }
private float k_SingleLineHeight { get { return RuleTileEditor.k_SingleLineHeight; } }
private float k_LabelWidth { get { return RuleTileEditor.k_LabelWidth; } }
void OnEnable()
{
if (m_Sprites == null)
m_Sprites = new List<KeyValuePair<Sprite, Sprite>>();
if (m_Rules == null)
m_Rules = new List<KeyValuePair<RuleTile.TilingRule, RuleTile.TilingRule>>();
if (m_SpriteList == null)
{
overrideTile.GetOverrides(m_Sprites);
m_SpriteList = new ReorderableList(m_Sprites, typeof(KeyValuePair<Sprite, Sprite>), false, true, false, false);
m_SpriteList.drawHeaderCallback = DrawSpriteHeader;
m_SpriteList.drawElementCallback = DrawSpriteElement;
m_SpriteList.elementHeight = k_DefaultElementHeight + k_PaddingBetweenRules;
}
if (m_RuleList == null)
{
overrideTile.GetOverrides(m_Rules);
m_RuleList = new ReorderableList(m_Rules, typeof(KeyValuePair<RuleTile.TilingRule, RuleTile.TilingRule>), false, true, false, false);
m_RuleList.drawHeaderCallback = DrawRuleHeader;
m_RuleList.drawElementCallback = DrawRuleElement;
m_RuleList.elementHeightCallback = GetRuleElementHeight;
}
}
public override void OnInspectorGUI()
{
serializedObject.UpdateIfRequiredOrScript();
EditorGUILayout.PropertyField(serializedObject.FindProperty("m_Tile"));
EditorGUILayout.PropertyField(serializedObject.FindProperty("m_Advanced"));
serializedObject.ApplyModifiedProperties();
if (!overrideTile.m_Advanced)
{
using (new EditorGUI.DisabledScope(overrideTile.m_Tile == null))
{
EditorGUI.BeginChangeCheck();
overrideTile.GetOverrides(m_Sprites);
m_SpriteList.list = m_Sprites;
m_SpriteList.DoLayoutList();
if (EditorGUI.EndChangeCheck())
{
for (int i = 0; i < targets.Length; i++)
{
RuleOverrideTile tile = targets[i] as RuleOverrideTile;
tile.ApplyOverrides(m_Sprites);
}
}
}
}
else
{
using (new EditorGUI.DisabledScope(overrideTile.m_Tile == null))
{
overrideTile.GetOverrides(m_Rules);
m_RuleList.list = m_Rules;
m_RuleList.DoLayoutList();
}
}
}
private void SaveTile()
{
EditorUtility.SetDirty(target);
SceneView.RepaintAll();
}
private void DrawSpriteElement(Rect rect, int index, bool selected, bool focused)
{
Sprite originalSprite = m_Sprites[index].Key;
Sprite overrideSprite = m_Sprites[index].Value;
rect.y += 2;
rect.height -= k_PaddingBetweenRules;
rect.xMax = rect.xMax / 2.0f;
using (new EditorGUI.DisabledScope(true))
EditorGUI.ObjectField(new Rect(rect.xMin, rect.yMin, rect.height, rect.height), originalSprite, typeof(Sprite), false);
rect.xMin = rect.xMax;
rect.xMax *= 2.0f;
EditorGUI.BeginChangeCheck();
overrideSprite = EditorGUI.ObjectField(new Rect(rect.xMin, rect.yMin, rect.height, rect.height), overrideSprite, typeof(Sprite), false) as Sprite;
if (EditorGUI.EndChangeCheck())
{
m_Sprites[index] = new KeyValuePair<Sprite, Sprite>(originalSprite, overrideSprite);
SaveTile();
}
}
private void DrawSpriteHeader(Rect rect)
{
float xMax = rect.xMax;
rect.xMax = rect.xMax / 2.0f;
GUI.Label(rect, "Original", EditorStyles.label);
rect.xMin = rect.xMax;
rect.xMax = xMax;
GUI.Label(rect, "Override", EditorStyles.label);
}
private void DrawRuleElement(Rect rect, int index, bool selected, bool focused)
{
RuleTile.TilingRule originalRule = m_Rules[index].Key;
RuleTile.TilingRule overrideRule = m_Rules[index].Value;
float matrixWidth = k_DefaultElementHeight;
float xMax = rect.xMax;
rect.xMax = rect.xMax / 2.0f + matrixWidth - 10f;
if (index != overrideTile.m_Tile.m_TilingRules.Count)
DrawOriginalRuleElement(rect, originalRule);
else
DrawOriginalRuleElement(rect, originalRule, true);
rect.xMin = rect.xMax;
rect.xMax = xMax;
EditorGUI.BeginChangeCheck();
if (index != overrideTile.m_Tile.m_TilingRules.Count)
DrawOverrideElement(rect, originalRule);
else
DrawOverrideDefaultElement(rect, overrideRule);
if (EditorGUI.EndChangeCheck())
SaveTile();
}
public void DrawOriginalRuleElement(Rect rect, RuleTile.TilingRule originalRule, bool isDefault = false)
{
using (new EditorGUI.DisabledScope(true))
{
float yPos = rect.yMin + 2f;
float height = rect.height - k_PaddingBetweenRules;
float matrixWidth = k_DefaultElementHeight;
Rect inspectorRect = new Rect(rect.xMin, yPos, rect.width - matrixWidth * 2f - 20f, height);
Rect matrixRect = new Rect(rect.xMax - matrixWidth * 2f - 10f, yPos, matrixWidth, k_DefaultElementHeight);
Rect spriteRect = new Rect(rect.xMax - matrixWidth - 5f, yPos, matrixWidth, k_DefaultElementHeight);
if (!isDefault)
RuleTileEditor.RuleInspectorOnGUI(inspectorRect, originalRule);
else
RuleOriginalDefaultInspectorOnGUI(inspectorRect, originalRule);
RuleTileEditor.RuleMatrixOnGUI(matrixRect, originalRule);
RuleTileEditor.SpriteOnGUI(spriteRect, originalRule);
}
}
private void DrawOverrideElement(Rect rect, RuleTile.TilingRule originalRule)
{
float yPos = rect.yMin + 2f;
float height = rect.height - k_PaddingBetweenRules;
float matrixWidth = k_DefaultElementHeight;
Rect inspectorRect = new Rect(rect.xMin, yPos, rect.width - matrixWidth - 10f, height);
Rect spriteRect = new Rect(rect.xMax - matrixWidth - 5f, yPos, matrixWidth, k_DefaultElementHeight);
RuleOverrideInspectorOnGUI(inspectorRect, originalRule);
RuleTile.TilingRule overrideRule = overrideTile[originalRule];
if (overrideRule != null)
RuleTileEditor.SpriteOnGUI(spriteRect, overrideRule);
}
private void RuleOriginalDefaultInspectorOnGUI(Rect rect, RuleTile.TilingRule originalRule)
{
float y = rect.yMin;
GUI.Label(new Rect(rect.xMin, y, k_LabelWidth, k_SingleLineHeight), "Rule");
EditorGUI.LabelField(new Rect(rect.xMin + k_LabelWidth, y, rect.width - k_LabelWidth, k_SingleLineHeight), "Default");
y += k_SingleLineHeight;
GUI.Label(new Rect(rect.xMin, y, k_LabelWidth, k_SingleLineHeight), "Collider");
EditorGUI.EnumPopup(new Rect(rect.xMin + k_LabelWidth, y, rect.width - k_LabelWidth, k_SingleLineHeight), originalRule.m_ColliderType);
y += k_SingleLineHeight;
}
private void RuleOverrideInspectorOnGUI(Rect rect, RuleTile.TilingRule originalRule)
{
RuleTile.TilingRule overrideRule = overrideTile[originalRule];
float y = rect.yMin;
EditorGUI.BeginChangeCheck();
GUI.Label(new Rect(rect.xMin, y, k_LabelWidth, k_SingleLineHeight), "Enabled");
bool enabled = EditorGUI.Toggle(new Rect(rect.xMin + k_LabelWidth, y, rect.width - k_LabelWidth, k_SingleLineHeight), overrideRule != null);
y += k_SingleLineHeight;
if (EditorGUI.EndChangeCheck())
{
if (enabled)
overrideTile[originalRule] = originalRule;
else
overrideTile[originalRule] = null;
overrideRule = overrideTile[originalRule];
}
if (overrideRule == null)
return;
GUI.Label(new Rect(rect.xMin, y, k_LabelWidth, k_SingleLineHeight), "Collider");
overrideRule.m_ColliderType = (Tile.ColliderType)EditorGUI.EnumPopup(new Rect(rect.xMin + k_LabelWidth, y, rect.width - k_LabelWidth, k_SingleLineHeight), overrideRule.m_ColliderType);
y += k_SingleLineHeight;
GUI.Label(new Rect(rect.xMin, y, k_LabelWidth, k_SingleLineHeight), "Output");
overrideRule.m_Output = (RuleTile.TilingRule.OutputSprite)EditorGUI.EnumPopup(new Rect(rect.xMin + k_LabelWidth, y, rect.width - k_LabelWidth, k_SingleLineHeight), overrideRule.m_Output);
y += k_SingleLineHeight;
if (overrideRule.m_Output == RuleTile.TilingRule.OutputSprite.Animation)
{
GUI.Label(new Rect(rect.xMin, y, k_LabelWidth, k_SingleLineHeight), "Speed");
overrideRule.m_AnimationSpeed = EditorGUI.FloatField(new Rect(rect.xMin + k_LabelWidth, y, rect.width - k_LabelWidth, k_SingleLineHeight), overrideRule.m_AnimationSpeed);
y += k_SingleLineHeight;
}
if (overrideRule.m_Output == RuleTile.TilingRule.OutputSprite.Random)
{
GUI.Label(new Rect(rect.xMin, y, k_LabelWidth, k_SingleLineHeight), "Noise");
overrideRule.m_PerlinScale = EditorGUI.Slider(new Rect(rect.xMin + k_LabelWidth, y, rect.width - k_LabelWidth, k_SingleLineHeight), overrideRule.m_PerlinScale, 0.001f, 0.999f);
y += k_SingleLineHeight;
GUI.Label(new Rect(rect.xMin, y, k_LabelWidth, k_SingleLineHeight), "Shuffle");
overrideRule.m_RandomTransform = (RuleTile.TilingRule.Transform)EditorGUI.EnumPopup(new Rect(rect.xMin + k_LabelWidth, y, rect.width - k_LabelWidth, k_SingleLineHeight), overrideRule.m_RandomTransform);
y += k_SingleLineHeight;
}
if (overrideRule.m_Output != RuleTile.TilingRule.OutputSprite.Single)
{
GUI.Label(new Rect(rect.xMin, y, k_LabelWidth, k_SingleLineHeight), "Size");
EditorGUI.BeginChangeCheck();
int newLength = EditorGUI.DelayedIntField(new Rect(rect.xMin + k_LabelWidth, y, rect.width - k_LabelWidth, k_SingleLineHeight), overrideRule.m_Sprites.Length);
if (EditorGUI.EndChangeCheck())
Array.Resize(ref overrideRule.m_Sprites, Math.Max(newLength, 1));
y += k_SingleLineHeight;
for (int i = 0; i < overrideRule.m_Sprites.Length; i++)
{
overrideRule.m_Sprites[i] = EditorGUI.ObjectField(new Rect(rect.xMin + k_LabelWidth, y, rect.width - k_LabelWidth, k_SingleLineHeight), overrideRule.m_Sprites[i], typeof(Sprite), false) as Sprite;
y += k_SingleLineHeight;
}
}
}
private void DrawOverrideDefaultElement(Rect rect, RuleTile.TilingRule originalRule)
{
float yPos = rect.yMin + 2f;
float height = rect.height - k_PaddingBetweenRules;
float matrixWidth = k_DefaultElementHeight;
Rect inspectorRect = new Rect(rect.xMin, yPos, rect.width - matrixWidth - 10f, height);
Rect spriteRect = new Rect(rect.xMax - matrixWidth - 5f, yPos, matrixWidth, k_DefaultElementHeight);
RuleOverrideDefaultInspectorOnGUI(inspectorRect, originalRule);
if (overrideTile.m_OverrideDefault.m_Enabled)
RuleTileEditor.SpriteOnGUI(spriteRect, overrideTile.m_OverrideDefault.m_TilingRule);
}
private void RuleOverrideDefaultInspectorOnGUI(Rect rect, RuleTile.TilingRule overrideRule)
{
float y = rect.yMin;
EditorGUI.BeginChangeCheck();
GUI.Label(new Rect(rect.xMin, y, k_LabelWidth, k_SingleLineHeight), "Enabled");
bool enabled = EditorGUI.Toggle(new Rect(rect.xMin + k_LabelWidth, y, rect.width - k_LabelWidth, k_SingleLineHeight), overrideTile.m_OverrideDefault.m_Enabled);
y += k_SingleLineHeight;
if (EditorGUI.EndChangeCheck())
{
overrideTile.m_OverrideDefault.m_Enabled = enabled;
overrideTile.m_OverrideDefault.m_TilingRule = overrideTile.m_OriginalDefault;
}
if (!enabled)
return;
GUI.Label(new Rect(rect.xMin, y, k_LabelWidth, k_SingleLineHeight), "Collider");
overrideRule.m_ColliderType = (Tile.ColliderType)EditorGUI.EnumPopup(new Rect(rect.xMin + k_LabelWidth, y, rect.width - k_LabelWidth, k_SingleLineHeight), overrideRule.m_ColliderType);
y += k_SingleLineHeight;
}
private void DrawRuleHeader(Rect rect)
{
overrideTile.Override();
float matrixWidth = k_DefaultElementHeight;
float xMax = rect.xMax;
rect.xMax = rect.xMax / 2.0f + matrixWidth - 10f;
GUI.Label(rect, "Original", EditorStyles.label);
rect.xMin = rect.xMax;
rect.xMax = xMax;
GUI.Label(rect, "Override", EditorStyles.label);
}
private float GetRuleElementHeight(int index)
{
if (index != overrideTile.m_Tile.m_TilingRules.Count)
{
var overrideRule = overrideTile[overrideTile.m_Tile.m_TilingRules[index]];
float overrideHeight = GetRuleElementHeight(overrideRule);
float originalHeight = GetRuleElementHeight(overrideTile.m_Tile.m_TilingRules[index]);
return Mathf.Max(overrideHeight, originalHeight);
}
else
{
var overrideRule = overrideTile.m_OverrideDefault.m_Enabled ? overrideTile.m_OverrideDefault.m_TilingRule : null;
float overrideHeight = GetRuleElementHeight(overrideRule);
float originalHeight = GetRuleElementHeight(new RuleTile.TilingRule());
return Mathf.Max(overrideHeight, originalHeight);
}
}
private float GetRuleElementHeight(RuleTile.TilingRule rule)
{
float height = k_DefaultElementHeight + k_PaddingBetweenRules;
if (rule != null)
{
switch (rule.m_Output)
{
case RuleTile.TilingRule.OutputSprite.Random:
height = k_DefaultElementHeight + k_SingleLineHeight * (rule.m_Sprites.Length + 3) + k_PaddingBetweenRules;
break;
case RuleTile.TilingRule.OutputSprite.Animation:
height = k_DefaultElementHeight + k_SingleLineHeight * (rule.m_Sprites.Length + 2) + k_PaddingBetweenRules;
break;
}
}
return height;
}
}
}

View file

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: dd977390416471341b10fd1278290da0
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View file

@ -0,0 +1,331 @@
using System;
using System.Collections.Generic;
using System.Linq;
using UnityEngine.Tilemaps;
namespace UnityEngine
{
[Serializable, CreateAssetMenu]
public class RuleOverrideTile : TileBase
{
public bool m_Advanced;
public OverrideTilingRule m_OverrideDefault = new OverrideTilingRule();
public List<OverrideTilingRule> m_OverrideTilingRules = new List<OverrideTilingRule>();
public List<TileSpritePair> m_Sprites = new List<TileSpritePair>();
public RuleTile m_Tile;
private RuleTile m_RuntimeTile;
public Sprite this[Sprite originalSprite]
{
get
{
foreach (var spritePair in m_Sprites)
{
if (spritePair.m_OriginalSprite == originalSprite)
{
return spritePair.m_OverrideSprite;
}
}
return null;
}
set
{
if (value == null)
{
m_Sprites = m_Sprites.Where(spritePair => spritePair.m_OriginalSprite != originalSprite).ToList();
}
else
{
foreach (var spritePair in m_Sprites)
{
if (spritePair.m_OriginalSprite == originalSprite)
{
spritePair.m_OverrideSprite = value;
return;
}
}
m_Sprites.Add(new TileSpritePair { m_OriginalSprite = originalSprite, m_OverrideSprite = value });
}
}
}
public RuleTile.TilingRule this[RuleTile.TilingRule originalRule]
{
get
{
if (!m_Tile)
{
return null;
}
var index = m_Tile.m_TilingRules.IndexOf(originalRule);
if (index == -1)
{
return null;
}
if (m_OverrideTilingRules.Count < index + 1)
{
return null;
}
return m_OverrideTilingRules[index].m_Enabled ? m_OverrideTilingRules[index].m_TilingRule : null;
}
set
{
if (!m_Tile)
{
return;
}
var index = m_Tile.m_TilingRules.IndexOf(originalRule);
if (index == -1)
{
return;
}
if (value == null)
{
if (m_OverrideTilingRules.Count < index + 1)
{
return;
}
m_OverrideTilingRules[index].m_Enabled = false;
while (m_OverrideTilingRules.Count > 0 && !m_OverrideTilingRules[m_OverrideTilingRules.Count - 1].m_Enabled)
{
m_OverrideTilingRules.RemoveAt(m_OverrideTilingRules.Count - 1);
}
}
else
{
while (m_OverrideTilingRules.Count < index + 1)
{
m_OverrideTilingRules.Add(new OverrideTilingRule());
}
m_OverrideTilingRules[index].m_Enabled = true;
m_OverrideTilingRules[index].m_TilingRule = CloneTilingRule(value);
m_OverrideTilingRules[index].m_TilingRule.m_Neighbors = null;
}
}
}
public RuleTile.TilingRule m_OriginalDefault
{
get
{
return new RuleTile.TilingRule
{
m_Sprites = new[] { m_Tile != null ? m_Tile.m_DefaultSprite : null },
m_ColliderType = m_Tile != null ? m_Tile.m_DefaultColliderType : Tile.ColliderType.None
};
}
}
public override bool GetTileAnimationData(Vector3Int position, ITilemap tilemap, ref TileAnimationData tileAnimationData)
{
if (!m_RuntimeTile)
{
Override();
}
return m_RuntimeTile.GetTileAnimationData(position, tilemap, ref tileAnimationData);
}
public override void GetTileData(Vector3Int position, ITilemap tilemap, ref TileData tileData)
{
if (!m_RuntimeTile)
{
Override();
}
m_RuntimeTile.GetTileData(position, tilemap, ref tileData);
}
public override void RefreshTile(Vector3Int position, ITilemap tilemap)
{
if (!m_RuntimeTile)
{
Override();
}
m_RuntimeTile.RefreshTile(position, tilemap);
}
public override bool StartUp(Vector3Int position, ITilemap tilemap, GameObject go)
{
Override();
return m_RuntimeTile.StartUp(position, tilemap, go);
}
public void ApplyOverrides(IList<KeyValuePair<Sprite, Sprite>> overrides)
{
if (overrides == null)
{
throw new ArgumentNullException("overrides");
}
for (var i = 0; i < overrides.Count; i++)
{
this[overrides[i].Key] = overrides[i].Value;
}
}
public void GetOverrides(List<KeyValuePair<Sprite, Sprite>> overrides)
{
if (overrides == null)
{
throw new ArgumentNullException("overrides");
}
overrides.Clear();
if (!m_Tile)
{
return;
}
var originalSprites = new List<Sprite>();
if (m_Tile.m_DefaultSprite)
{
originalSprites.Add(m_Tile.m_DefaultSprite);
}
foreach (var rule in m_Tile.m_TilingRules)
foreach (var sprite in rule.m_Sprites)
{
if (sprite && !originalSprites.Contains(sprite))
{
originalSprites.Add(sprite);
}
}
foreach (var sprite in originalSprites)
{
overrides.Add(new KeyValuePair<Sprite, Sprite>(sprite, this[sprite]));
}
}
public void ApplyOverrides(IList<KeyValuePair<RuleTile.TilingRule, RuleTile.TilingRule>> overrides)
{
if (overrides == null)
{
throw new ArgumentNullException("overrides");
}
for (var i = 0; i < overrides.Count; i++)
{
this[overrides[i].Key] = overrides[i].Value;
}
}
public void GetOverrides(List<KeyValuePair<RuleTile.TilingRule, RuleTile.TilingRule>> overrides)
{
if (overrides == null)
{
throw new ArgumentNullException("overrides");
}
overrides.Clear();
if (!m_Tile)
{
return;
}
foreach (var originalRule in m_Tile.m_TilingRules)
{
var overrideRule = this[originalRule];
overrides.Add(new KeyValuePair<RuleTile.TilingRule, RuleTile.TilingRule>(originalRule, overrideRule));
}
overrides.Add(new KeyValuePair<RuleTile.TilingRule, RuleTile.TilingRule>(m_OriginalDefault, m_OverrideDefault.m_TilingRule));
}
public void Override()
{
m_RuntimeTile = m_Tile ? Instantiate(m_Tile) : new RuleTile();
m_RuntimeTile.m_Self = this;
if (!m_Advanced)
{
if (m_RuntimeTile.m_DefaultSprite)
{
m_RuntimeTile.m_DefaultSprite = this[m_RuntimeTile.m_DefaultSprite];
}
if (m_RuntimeTile.m_TilingRules != null)
{
foreach (var rule in m_RuntimeTile.m_TilingRules)
{
for (var i = 0; i < rule.m_Sprites.Length; i++)
{
if (rule.m_Sprites[i])
{
rule.m_Sprites[i] = this[rule.m_Sprites[i]];
}
}
}
}
}
else
{
if (m_OverrideDefault.m_Enabled)
{
m_RuntimeTile.m_DefaultSprite = m_OverrideDefault.m_TilingRule.m_Sprites.Length > 0
? m_OverrideDefault.m_TilingRule.m_Sprites[0]
: null;
m_RuntimeTile.m_DefaultColliderType = m_OverrideDefault.m_TilingRule.m_ColliderType;
}
if (m_RuntimeTile.m_TilingRules != null)
{
for (var i = 0; i < m_RuntimeTile.m_TilingRules.Count; i++)
{
var originalRule = m_RuntimeTile.m_TilingRules[i];
var overrideRule = this[m_Tile.m_TilingRules[i]];
if (overrideRule == null)
{
continue;
}
CopyTilingRule(overrideRule, originalRule, false);
}
}
}
}
public RuleTile.TilingRule CloneTilingRule(RuleTile.TilingRule from)
{
var clone = new RuleTile.TilingRule();
CopyTilingRule(from, clone, true);
return clone;
}
public void CopyTilingRule(RuleTile.TilingRule from, RuleTile.TilingRule to, bool copyRule)
{
if (copyRule)
{
to.m_Neighbors = from.m_Neighbors;
to.m_RuleTransform = from.m_RuleTransform;
}
to.m_Sprites = from.m_Sprites.Clone() as Sprite[];
to.m_AnimationSpeed = from.m_AnimationSpeed;
to.m_PerlinScale = from.m_PerlinScale;
to.m_Output = from.m_Output;
to.m_ColliderType = from.m_ColliderType;
to.m_RandomTransform = from.m_RandomTransform;
}
[Serializable]
public class TileSpritePair
{
public Sprite m_OriginalSprite;
public Sprite m_OverrideSprite;
}
[Serializable]
public class OverrideTilingRule
{
public bool m_Enabled;
public RuleTile.TilingRule m_TilingRule = new RuleTile.TilingRule();
}
}
}

View file

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 4c779848d9dd029409ca676b49e10a18
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View file

@ -0,0 +1,10 @@
fileFormatVersion: 2
guid: 8f0e4a19192261d448b776e63139448e
folderAsset: yes
timeCreated: 1501789590
licenseType: Pro
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View file

@ -0,0 +1,10 @@
fileFormatVersion: 2
guid: 6d62b55c63b75aa468f7dc342717b87f
folderAsset: yes
timeCreated: 1501789661
licenseType: Pro
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View file

@ -0,0 +1,10 @@
fileFormatVersion: 2
guid: 32b801acc992cb24298d963cc554c0a2
folderAsset: yes
timeCreated: 1501789682
licenseType: Pro
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View file

@ -0,0 +1,402 @@
using System;
using System.Collections.Generic;
using System.Reflection;
using UnityEditor.Sprites;
using UnityEditorInternal;
using UnityEngine;
using UnityEngine.Networking;
using UnityEngine.Tilemaps;
using Object = UnityEngine.Object;
namespace UnityEditor
{
[CustomEditor(typeof(RuleTile))]
[CanEditMultipleObjects]
internal class RuleTileEditor : Editor
{
private const string s_XIconString = "iVBORw0KGgoAAAANSUhEUgAAAA8AAAAPCAYAAAA71pVKAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAAYdEVYdFNvZnR3YXJlAHBhaW50Lm5ldCA0LjAuNWWFMmUAAABoSURBVDhPnY3BDcAgDAOZhS14dP1O0x2C/LBEgiNSHvfwyZabmV0jZRUpq2zi6f0DJwdcQOEdwwDLypF0zHLMa9+NQRxkQ+ACOT2STVw/q8eY1346ZlE54sYAhVhSDrjwFymrSFnD2gTZpls2OvFUHAAAAABJRU5ErkJggg==";
private const string s_Arrow0 = "iVBORw0KGgoAAAANSUhEUgAAAA8AAAAPCAYAAAA71pVKAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAAYdEVYdFNvZnR3YXJlAHBhaW50Lm5ldCA0LjAuNWWFMmUAAACYSURBVDhPzZExDoQwDATzE4oU4QXXcgUFj+YxtETwgpMwXuFcwMFSRMVKKwzZcWzhiMg91jtg34XIntkre5EaT7yjjhI9pOD5Mw5k2X/DdUwFr3cQ7Pu23E/BiwXyWSOxrNqx+ewnsayam5OLBtbOGPUM/r93YZL4/dhpR/amwByGFBz170gNChA6w5bQQMqramBTgJ+Z3A58WuWejPCaHQAAAABJRU5ErkJggg==";
private const string s_Arrow1 = "iVBORw0KGgoAAAANSUhEUgAAAA8AAAAPCAYAAAA71pVKAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAAYdEVYdFNvZnR3YXJlAHBhaW50Lm5ldCA0LjAuNWWFMmUAAABqSURBVDhPxYzBDYAgEATpxYcd+PVr0fZ2siZrjmMhFz6STIiDs8XMlpEyi5RkO/d66TcgJUB43JfNBqRkSEYDnYjhbKD5GIUkDqRDwoH3+NgTAw+bL/aoOP4DOgH+iwECEt+IlFmkzGHlAYKAWF9R8zUnAAAAAElFTkSuQmCC";
private const string s_Arrow2 = "iVBORw0KGgoAAAANSUhEUgAAAA8AAAAPCAYAAAA71pVKAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAAYdEVYdFNvZnR3YXJlAHBhaW50Lm5ldCA0LjAuNWWFMmUAAAC0SURBVDhPjVE5EsIwDMxPKFKYF9CagoJH8xhaMskLmEGsjOSRkBzYmU2s9a58TUQUmCH1BWEHweuKP+D8tphrWcAHuIGrjPnPNY8X2+DzEWE+FzrdrkNyg2YGNNfRGlyOaZDJOxBrDhgOowaYW8UW0Vau5ZkFmXbbDr+CzOHKmLinAXMEePyZ9dZkZR+s5QX2O8DY3zZ/sgYcdDqeEVp8516o0QQV1qeMwg6C91toYoLoo+kNt/tpKQEVvFQAAAAASUVORK5CYII=";
private const string s_Arrow3 = "iVBORw0KGgoAAAANSUhEUgAAAA8AAAAPCAYAAAA71pVKAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAAYdEVYdFNvZnR3YXJlAHBhaW50Lm5ldCA0LjAuNWWFMmUAAAB2SURBVDhPzY1LCoAwEEPnLi48gW5d6p31bH5SMhp0Cq0g+CCLxrzRPqMZ2pRqKG4IqzJc7JepTlbRZXYpWTg4RZE1XAso8VHFKNhQuTjKtZvHUNCEMogO4K3BhvMn9wP4EzoPZ3n0AGTW5fiBVzLAAYTP32C2Ay3agtu9V/9PAAAAAElFTkSuQmCC";
private const string s_Arrow5 = "iVBORw0KGgoAAAANSUhEUgAAAA8AAAAPCAYAAAA71pVKAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAAYdEVYdFNvZnR3YXJlAHBhaW50Lm5ldCA0LjAuNWWFMmUAAABqSURBVDhPnY3BCYBADASvFx924NevRdvbyoLBmNuDJQMDGjNxAFhK1DyUQ9fvobCdO+j7+sOKj/uSB+xYHZAxl7IR1wNTXJeVcaAVU+614uWfCT9mVUhknMlxDokd15BYsQrJFHeUQ0+MB5ErsPi/6hO1AAAAAElFTkSuQmCC";
private const string s_Arrow6 = "iVBORw0KGgoAAAANSUhEUgAAAA8AAAAPCAYAAAA71pVKAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAAYdEVYdFNvZnR3YXJlAHBhaW50Lm5ldCA0LjAuNWWFMmUAAACaSURBVDhPxZExEkAwEEVzE4UiTqClUDi0w2hlOIEZsV82xCZmQuPPfFn8t1mirLWf7S5flQOXjd64vCuEKWTKVt+6AayH3tIa7yLg6Qh2FcKFB72jBgJeziA1CMHzeaNHjkfwnAK86f3KUafU2ClHIJSzs/8HHLv09M3SaMCxS7ljw/IYJWzQABOQZ66x4h614ahTCL/WT7BSO51b5Z5hSx88AAAAAElFTkSuQmCC";
private const string s_Arrow7 = "iVBORw0KGgoAAAANSUhEUgAAAA8AAAAPCAYAAAA71pVKAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAAYdEVYdFNvZnR3YXJlAHBhaW50Lm5ldCA0LjAuNWWFMmUAAABQSURBVDhPYxh8QNle/T8U/4MKEQdAmsz2eICx6W530gygr2aQBmSMphkZYxqErAEXxusKfAYQ7XyyNMIAsgEkaYQBkAFkaYQBsjXSGDAwAAD193z4luKPrAAAAABJRU5ErkJggg==";
private const string s_Arrow8 = "iVBORw0KGgoAAAANSUhEUgAAAA8AAAAPCAYAAAA71pVKAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAAYdEVYdFNvZnR3YXJlAHBhaW50Lm5ldCA0LjAuNWWFMmUAAACYSURBVDhPxZE9DoAwCIW9iUOHegJXHRw8tIdx1egJTMSHAeMPaHSR5KVQ+KCkCRF91mdz4VDEWVzXTBgg5U1N5wahjHzXS3iFFVRxAygNVaZxJ6VHGIl2D6oUXP0ijlJuTp724FnID1Lq7uw2QM5+thoKth0N+GGyA7IA3+yM77Ag1e2zkey5gCdAg/h8csy+/89v7E+YkgUntOWeVt2SfAAAAABJRU5ErkJggg==";
private const string s_MirrorX = "iVBORw0KGgoAAAANSUhEUgAAAA8AAAAPCAYAAAA71pVKAAAABGdBTUEAALGPC/xhBQAAAAlwSFlzAAAOwQAADsEBuJFr7QAAABh0RVh0U29mdHdhcmUAcGFpbnQubmV0IDQuMC41ZYUyZQAAAG1JREFUOE+lj9ENwCAIRB2IFdyRfRiuDSaXAF4MrR9P5eRhHGb2Gxp2oaEjIovTXSrAnPNx6hlgyCZ7o6omOdYOldGIZhAziEmOTSfigLV0RYAB9y9f/7kO8L3WUaQyhCgz0dmCL9CwCw172HgBeyG6oloC8fAAAAAASUVORK5CYII=";
private const string s_MirrorY = "iVBORw0KGgoAAAANSUhEUgAAAA8AAAAPCAYAAAA71pVKAAAABGdBTUEAALGPC/xhBQAAAAlwSFlzAAAOwgAADsIBFShKgAAAABh0RVh0U29mdHdhcmUAcGFpbnQubmV0IDQuMC41ZYUyZQAAAG9JREFUOE+djckNACEMAykoLdAjHbPyw1IOJ0L7mAejjFlm9hspyd77Kk+kBAjPOXcakJIh6QaKyOE0EB5dSPJAiUmOiL8PMVGxugsP/0OOib8vsY8yYwy6gRyC8CB5QIWgCMKBLgRSkikEUr5h6wOPWfMoCYILdgAAAABJRU5ErkJggg==";
private const string s_Rotated = "iVBORw0KGgoAAAANSUhEUgAAAA8AAAAPCAYAAAA71pVKAAAABGdBTUEAALGPC/xhBQAAAAlwSFlzAAAOwQAADsEBuJFr7QAAABh0RVh0U29mdHdhcmUAcGFpbnQubmV0IDQuMC41ZYUyZQAAAHdJREFUOE+djssNwCAMQxmIFdgx+2S4Vj4YxWlQgcOT8nuG5u5C732Sd3lfLlmPMR4QhXgrTQaimUlA3EtD+CJlBuQ7aUAUMjEAv9gWCQNEPhHJUkYfZ1kEpcxDzioRzGIlr0Qwi0r+Q5rTgM+AAVcygHgt7+HtBZs/2QVWP8ahAAAAAElFTkSuQmCC";
private static Texture2D[] s_Arrows;
public static Texture2D[] arrows
{
get
{
if (s_Arrows == null)
{
s_Arrows = new Texture2D[10];
s_Arrows[0] = Base64ToTexture(s_Arrow0);
s_Arrows[1] = Base64ToTexture(s_Arrow1);
s_Arrows[2] = Base64ToTexture(s_Arrow2);
s_Arrows[3] = Base64ToTexture(s_Arrow3);
s_Arrows[5] = Base64ToTexture(s_Arrow5);
s_Arrows[6] = Base64ToTexture(s_Arrow6);
s_Arrows[7] = Base64ToTexture(s_Arrow7);
s_Arrows[8] = Base64ToTexture(s_Arrow8);
s_Arrows[9] = Base64ToTexture(s_XIconString);
}
return s_Arrows;
}
}
private static Texture2D[] s_AutoTransforms;
public static Texture2D[] autoTransforms
{
get
{
if (s_AutoTransforms == null)
{
s_AutoTransforms = new Texture2D[3];
s_AutoTransforms[0] = Base64ToTexture(s_Rotated);
s_AutoTransforms[1] = Base64ToTexture(s_MirrorX);
s_AutoTransforms[2] = Base64ToTexture(s_MirrorY);
}
return s_AutoTransforms;
}
}
private ReorderableList m_ReorderableList;
public RuleTile tile { get { return (target as RuleTile); } }
private Rect m_ListRect;
internal const float k_DefaultElementHeight = 48f;
internal const float k_PaddingBetweenRules = 13f;
internal const float k_SingleLineHeight = 16f;
internal const float k_LabelWidth = 53f;
public void OnEnable()
{
if (tile.m_TilingRules == null)
tile.m_TilingRules = new List<RuleTile.TilingRule>();
m_ReorderableList = new ReorderableList(tile.m_TilingRules, typeof(RuleTile.TilingRule), true, true, true, true);
m_ReorderableList.drawHeaderCallback = OnDrawHeader;
m_ReorderableList.drawElementCallback = OnDrawElement;
m_ReorderableList.elementHeightCallback = GetElementHeight;
m_ReorderableList.onReorderCallback = ListUpdated;
m_ReorderableList.onAddCallback = OnAddElement;
}
private void ListUpdated(ReorderableList list)
{
SaveTile();
}
private float GetElementHeight(int index)
{
if (tile.m_TilingRules != null && tile.m_TilingRules.Count > 0)
{
switch (tile.m_TilingRules[index].m_Output)
{
case RuleTile.TilingRule.OutputSprite.Random:
return k_DefaultElementHeight + k_SingleLineHeight*(tile.m_TilingRules[index].m_Sprites.Length + 3) + k_PaddingBetweenRules;
case RuleTile.TilingRule.OutputSprite.Animation:
return k_DefaultElementHeight + k_SingleLineHeight*(tile.m_TilingRules[index].m_Sprites.Length + 2) + k_PaddingBetweenRules;
}
}
return k_DefaultElementHeight + k_PaddingBetweenRules;
}
private void OnDrawElement(Rect rect, int index, bool isactive, bool isfocused)
{
RuleTile.TilingRule rule = tile.m_TilingRules[index];
float yPos = rect.yMin + 2f;
float height = rect.height - k_PaddingBetweenRules;
float matrixWidth = k_DefaultElementHeight;
Rect inspectorRect = new Rect(rect.xMin, yPos, rect.width - matrixWidth * 2f - 20f, height);
Rect matrixRect = new Rect(rect.xMax - matrixWidth * 2f - 10f, yPos, matrixWidth, k_DefaultElementHeight);
Rect spriteRect = new Rect(rect.xMax - matrixWidth - 5f, yPos, matrixWidth, k_DefaultElementHeight);
EditorGUI.BeginChangeCheck();
RuleInspectorOnGUI(inspectorRect, rule);
RuleMatrixOnGUI(matrixRect, rule);
SpriteOnGUI(spriteRect, rule);
if (EditorGUI.EndChangeCheck())
SaveTile();
}
private void OnAddElement(ReorderableList list)
{
RuleTile.TilingRule rule = new RuleTile.TilingRule();
rule.m_Output = RuleTile.TilingRule.OutputSprite.Single;
rule.m_Sprites[0] = tile.m_DefaultSprite;
rule.m_ColliderType = tile.m_DefaultColliderType;
tile.m_TilingRules.Add(rule);
}
private void SaveTile()
{
EditorUtility.SetDirty(target);
SceneView.RepaintAll();
}
private void OnDrawHeader(Rect rect)
{
GUI.Label(rect, "Tiling Rules");
}
public override void OnInspectorGUI()
{
tile.m_DefaultSprite = EditorGUILayout.ObjectField("Default Sprite", tile.m_DefaultSprite, typeof(Sprite), false) as Sprite;
tile.m_DefaultColliderType = (Tile.ColliderType)EditorGUILayout.EnumPopup("Default Collider", tile.m_DefaultColliderType);
EditorGUILayout.Space();
if (m_ReorderableList != null && tile.m_TilingRules != null)
m_ReorderableList.DoLayoutList();
}
internal static void RuleMatrixOnGUI(Rect rect, RuleTile.TilingRule tilingRule)
{
Handles.color = EditorGUIUtility.isProSkin ? new Color(1f, 1f, 1f, 0.2f) : new Color(0f, 0f, 0f, 0.2f);
int index = 0;
float w = rect.width / 3f;
float h = rect.height / 3f;
for (int y = 0; y <= 3; y++)
{
float top = rect.yMin + y * h;
Handles.DrawLine(new Vector3(rect.xMin, top), new Vector3(rect.xMax, top));
}
for (int x = 0; x <= 3; x++)
{
float left = rect.xMin + x * w;
Handles.DrawLine(new Vector3(left, rect.yMin), new Vector3(left, rect.yMax));
}
Handles.color = Color.white;
for (int y = 0; y <= 2; y++)
{
for (int x = 0; x <= 2; x++)
{
Rect r = new Rect(rect.xMin + x * w, rect.yMin + y * h, w - 1, h - 1);
if (x != 1 || y != 1)
{
switch (tilingRule.m_Neighbors[index])
{
case RuleTile.TilingRule.Neighbor.This:
GUI.DrawTexture(r, arrows[y*3 + x]);
break;
case RuleTile.TilingRule.Neighbor.NotThis:
GUI.DrawTexture(r, arrows[9]);
break;
}
if (Event.current.type == EventType.MouseDown && r.Contains(Event.current.mousePosition))
{
int change = 1;
if (Event.current.button == 1)
change = -1;
tilingRule.m_Neighbors[index] = (RuleTile.TilingRule.Neighbor) (((int)tilingRule.m_Neighbors[index] + change) % 3);
GUI.changed = true;
Event.current.Use();
}
index++;
}
else
{
switch (tilingRule.m_RuleTransform)
{
case RuleTile.TilingRule.Transform.Rotated:
GUI.DrawTexture(r, autoTransforms[0]);
break;
case RuleTile.TilingRule.Transform.MirrorX:
GUI.DrawTexture(r, autoTransforms[1]);
break;
case RuleTile.TilingRule.Transform.MirrorY:
GUI.DrawTexture(r, autoTransforms[2]);
break;
}
if (Event.current.type == EventType.MouseDown && r.Contains(Event.current.mousePosition))
{
tilingRule.m_RuleTransform = (RuleTile.TilingRule.Transform)(((int)tilingRule.m_RuleTransform + 1) % 4);
GUI.changed = true;
Event.current.Use();
}
}
}
}
}
private static void OnSelect(object userdata)
{
MenuItemData data = (MenuItemData) userdata;
data.m_Rule.m_RuleTransform = data.m_NewValue;
}
private class MenuItemData
{
public RuleTile.TilingRule m_Rule;
public RuleTile.TilingRule.Transform m_NewValue;
public MenuItemData(RuleTile.TilingRule mRule, RuleTile.TilingRule.Transform mNewValue)
{
this.m_Rule = mRule;
this.m_NewValue = mNewValue;
}
}
internal static void SpriteOnGUI(Rect rect, RuleTile.TilingRule tilingRule)
{
tilingRule.m_Sprites[0] = EditorGUI.ObjectField(new Rect(rect.xMax - rect.height, rect.yMin, rect.height, rect.height), tilingRule.m_Sprites[0], typeof (Sprite), false) as Sprite;
}
internal static void RuleInspectorOnGUI(Rect rect, RuleTile.TilingRule tilingRule)
{
float y = rect.yMin;
EditorGUI.BeginChangeCheck();
GUI.Label(new Rect(rect.xMin, y, k_LabelWidth, k_SingleLineHeight), "Rule");
tilingRule.m_RuleTransform = (RuleTile.TilingRule.Transform)EditorGUI.EnumPopup(new Rect(rect.xMin + k_LabelWidth, y, rect.width - k_LabelWidth, k_SingleLineHeight), tilingRule.m_RuleTransform);
y += k_SingleLineHeight;
GUI.Label(new Rect(rect.xMin, y, k_LabelWidth, k_SingleLineHeight), "Collider");
tilingRule.m_ColliderType = (Tile.ColliderType)EditorGUI.EnumPopup(new Rect(rect.xMin + k_LabelWidth, y, rect.width - k_LabelWidth, k_SingleLineHeight), tilingRule.m_ColliderType);
y += k_SingleLineHeight;
GUI.Label(new Rect(rect.xMin, y, k_LabelWidth, k_SingleLineHeight), "Output");
tilingRule.m_Output = (RuleTile.TilingRule.OutputSprite)EditorGUI.EnumPopup(new Rect(rect.xMin + k_LabelWidth, y, rect.width - k_LabelWidth, k_SingleLineHeight), tilingRule.m_Output);
y += k_SingleLineHeight;
if (tilingRule.m_Output == RuleTile.TilingRule.OutputSprite.Animation)
{
GUI.Label(new Rect(rect.xMin, y, k_LabelWidth, k_SingleLineHeight), "Speed");
tilingRule.m_AnimationSpeed = EditorGUI.FloatField(new Rect(rect.xMin + k_LabelWidth, y, rect.width - k_LabelWidth, k_SingleLineHeight), tilingRule.m_AnimationSpeed);
y += k_SingleLineHeight;
}
if (tilingRule.m_Output == RuleTile.TilingRule.OutputSprite.Random)
{
GUI.Label(new Rect(rect.xMin, y, k_LabelWidth, k_SingleLineHeight), "Noise");
tilingRule.m_PerlinScale = EditorGUI.Slider(new Rect(rect.xMin + k_LabelWidth, y, rect.width - k_LabelWidth, k_SingleLineHeight), tilingRule.m_PerlinScale, 0.001f, 0.999f);
y += k_SingleLineHeight;
GUI.Label(new Rect(rect.xMin, y, k_LabelWidth, k_SingleLineHeight), "Shuffle");
tilingRule.m_RandomTransform = (RuleTile.TilingRule.Transform)EditorGUI.EnumPopup(new Rect(rect.xMin + k_LabelWidth, y, rect.width - k_LabelWidth, k_SingleLineHeight), tilingRule.m_RandomTransform);
y += k_SingleLineHeight;
}
if (tilingRule.m_Output != RuleTile.TilingRule.OutputSprite.Single)
{
GUI.Label(new Rect(rect.xMin, y, k_LabelWidth, k_SingleLineHeight), "Size");
EditorGUI.BeginChangeCheck();
int newLength = EditorGUI.DelayedIntField(new Rect(rect.xMin + k_LabelWidth, y, rect.width - k_LabelWidth, k_SingleLineHeight), tilingRule.m_Sprites.Length);
if (EditorGUI.EndChangeCheck())
Array.Resize(ref tilingRule.m_Sprites, Math.Max(newLength, 1));
y += k_SingleLineHeight;
for (int i = 0; i < tilingRule.m_Sprites.Length; i++)
{
tilingRule.m_Sprites[i] = EditorGUI.ObjectField(new Rect(rect.xMin + k_LabelWidth, y, rect.width - k_LabelWidth, k_SingleLineHeight), tilingRule.m_Sprites[i], typeof(Sprite), false) as Sprite;
y += k_SingleLineHeight;
}
}
}
public override Texture2D RenderStaticPreview(string assetPath, Object[] subAssets, int width, int height)
{
if (tile.m_DefaultSprite != null)
{
Type t = GetType("UnityEditor.SpriteUtility");
if (t != null)
{
MethodInfo method = t.GetMethod("RenderStaticPreview", new Type[] {typeof (Sprite), typeof (Color), typeof (int), typeof (int)});
if (method != null)
{
object ret = method.Invoke("RenderStaticPreview", new object[] {tile.m_DefaultSprite, Color.white, width, height});
if (ret is Texture2D)
return ret as Texture2D;
}
}
}
return base.RenderStaticPreview(assetPath, subAssets, width, height);
}
private static Type GetType(string TypeName)
{
var type = Type.GetType(TypeName);
if (type != null)
return type;
if (TypeName.Contains("."))
{
var assemblyName = TypeName.Substring(0, TypeName.IndexOf('.'));
var assembly = Assembly.Load(assemblyName);
if (assembly == null)
return null;
type = assembly.GetType(TypeName);
if (type != null)
return type;
}
var currentAssembly = Assembly.GetExecutingAssembly();
var referencedAssemblies = currentAssembly.GetReferencedAssemblies();
foreach (var assemblyName in referencedAssemblies)
{
var assembly = Assembly.Load(assemblyName);
if (assembly != null)
{
type = assembly.GetType(TypeName);
if (type != null)
return type;
}
}
return null;
}
private static Texture2D Base64ToTexture(string base64)
{
Texture2D t = new Texture2D(1, 1);
t.hideFlags = HideFlags.HideAndDontSave;
t.LoadImage(System.Convert.FromBase64String(base64));
return t;
}
[Serializable]
class RuleTileRuleWrapper
{
[SerializeField]
public List<RuleTile.TilingRule> rules = new List<RuleTile.TilingRule>();
}
[MenuItem("CONTEXT/RuleTile/Copy All Rules")]
private static void CopyAllRules(MenuCommand item)
{
RuleTile tile = item.context as RuleTile;
if (tile == null)
return;
RuleTileRuleWrapper rulesWrapper = new RuleTileRuleWrapper();
rulesWrapper.rules = tile.m_TilingRules;
var rulesJson = EditorJsonUtility.ToJson(rulesWrapper);
EditorGUIUtility.systemCopyBuffer = rulesJson;
}
[MenuItem("CONTEXT/RuleTile/Paste Rules")]
private static void PasteRules(MenuCommand item)
{
RuleTile tile = item.context as RuleTile;
if (tile == null)
return;
try
{
RuleTileRuleWrapper rulesWrapper = new RuleTileRuleWrapper();
EditorJsonUtility.FromJsonOverwrite(EditorGUIUtility.systemCopyBuffer, rulesWrapper);
tile.m_TilingRules.AddRange(rulesWrapper.rules);
}
catch (Exception e)
{
Debug.LogError("Unable to paste rules from system copy buffer");
}
}
}
}

View file

@ -0,0 +1,13 @@
fileFormatVersion: 2
guid: 139f9377103555b49b8dcd62686df3bf
timeCreated: 1501789622
licenseType: Pro
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View file

@ -0,0 +1,333 @@
using System;
using System.Collections.Generic;
using UnityEngine.Tilemaps;
namespace UnityEngine
{
[Serializable, CreateAssetMenu]
public class RuleTile : TileBase
{
private static readonly int[,] RotatedOrMirroredIndexes =
{
{ 2, 4, 7, 1, 6, 0, 3, 5 }, // 90
{ 7, 6, 5, 4, 3, 2, 1, 0 }, // 180, XY
{ 5, 3, 0, 6, 1, 7, 4, 2 }, // 270
{ 2, 1, 0, 4, 3, 7, 6, 5 }, // X
{ 5, 6, 7, 3, 4, 0, 1, 2 } // Y
};
private static readonly int NeighborCount = 8;
public Tile.ColliderType m_DefaultColliderType = Tile.ColliderType.Sprite;
public Sprite m_DefaultSprite;
[HideInInspector] public List<TilingRule> m_TilingRules;
private TileBase[] m_CachedNeighboringTiles = new TileBase[NeighborCount];
private TileBase m_OverrideSelf;
public TileBase m_Self
{
get => m_OverrideSelf ? m_OverrideSelf : this;
set => m_OverrideSelf = value;
}
public override void GetTileData(Vector3Int position, ITilemap tilemap, ref TileData tileData)
{
TileBase[] neighboringTiles = null;
GetMatchingNeighboringTiles(tilemap, position, ref neighboringTiles);
var iden = Matrix4x4.identity;
tileData.sprite = m_DefaultSprite;
tileData.colliderType = m_DefaultColliderType;
tileData.flags = TileFlags.LockTransform;
tileData.transform = iden;
foreach (var rule in m_TilingRules)
{
var transform = iden;
if (RuleMatches(rule, ref neighboringTiles, ref transform))
{
switch (rule.m_Output)
{
case TilingRule.OutputSprite.Single:
case TilingRule.OutputSprite.Animation:
tileData.sprite = rule.m_Sprites[0];
break;
case TilingRule.OutputSprite.Random:
var index = Mathf.Clamp(
Mathf.FloorToInt(GetPerlinValue(position, rule.m_PerlinScale, 100000f) * rule.m_Sprites.Length),
0,
rule.m_Sprites.Length - 1);
tileData.sprite = rule.m_Sprites[index];
if (rule.m_RandomTransform != TilingRule.Transform.Fixed)
{
transform = ApplyRandomTransform(rule.m_RandomTransform, transform, rule.m_PerlinScale, position);
}
break;
}
tileData.transform = transform;
tileData.colliderType = rule.m_ColliderType;
break;
}
}
}
private static float GetPerlinValue(Vector3Int position, float scale, float offset)
{
return Mathf.PerlinNoise((position.x + offset) * scale, (position.y + offset) * scale);
}
public override bool GetTileAnimationData(Vector3Int position, ITilemap tilemap, ref TileAnimationData tileAnimationData)
{
TileBase[] neighboringTiles = null;
var iden = Matrix4x4.identity;
foreach (var rule in m_TilingRules)
{
if (rule.m_Output == TilingRule.OutputSprite.Animation)
{
var transform = iden;
GetMatchingNeighboringTiles(tilemap, position, ref neighboringTiles);
if (RuleMatches(rule, ref neighboringTiles, ref transform))
{
tileAnimationData.animatedSprites = rule.m_Sprites;
tileAnimationData.animationSpeed = rule.m_AnimationSpeed;
return true;
}
}
}
return false;
}
public override void RefreshTile(Vector3Int location, ITilemap tileMap)
{
if (m_TilingRules != null && m_TilingRules.Count > 0)
{
for (var y = -1; y <= 1; y++)
for (var x = -1; x <= 1; x++)
{
base.RefreshTile(location + new Vector3Int(x, y, 0), tileMap);
}
}
else
{
base.RefreshTile(location, tileMap);
}
}
public bool RuleMatches(TilingRule rule, ref TileBase[] neighboringTiles, ref Matrix4x4 transform)
{
// Check rule against rotations of 0, 90, 180, 270
for (var angle = 0; angle <= (rule.m_RuleTransform == TilingRule.Transform.Rotated ? 270 : 0); angle += 90)
{
if (RuleMatches(rule, ref neighboringTiles, angle))
{
transform = Matrix4x4.TRS(Vector3.zero, Quaternion.Euler(0f, 0f, -angle), Vector3.one);
return true;
}
}
// Check rule against x-axis mirror
if (rule.m_RuleTransform == TilingRule.Transform.MirrorX && RuleMatches(rule, ref neighboringTiles, true, false))
{
transform = Matrix4x4.TRS(Vector3.zero, Quaternion.identity, new Vector3(-1f, 1f, 1f));
return true;
}
// Check rule against y-axis mirror
if (rule.m_RuleTransform == TilingRule.Transform.MirrorY && RuleMatches(rule, ref neighboringTiles, false, true))
{
transform = Matrix4x4.TRS(Vector3.zero, Quaternion.identity, new Vector3(1f, -1f, 1f));
return true;
}
return false;
}
private static Matrix4x4 ApplyRandomTransform(TilingRule.Transform type, Matrix4x4 original, float perlinScale, Vector3Int position)
{
var perlin = GetPerlinValue(position, perlinScale, 200000f);
switch (type)
{
case TilingRule.Transform.MirrorX:
return original * Matrix4x4.TRS(Vector3.zero, Quaternion.identity, new Vector3(perlin < 0.5 ? 1f : -1f, 1f, 1f));
case TilingRule.Transform.MirrorY:
return original * Matrix4x4.TRS(Vector3.zero, Quaternion.identity, new Vector3(1f, perlin < 0.5 ? 1f : -1f, 1f));
case TilingRule.Transform.Rotated:
var angle = Mathf.Clamp(Mathf.FloorToInt(perlin * 4), 0, 3) * 90;
return Matrix4x4.TRS(Vector3.zero, Quaternion.Euler(0f, 0f, -angle), Vector3.one);
}
return original;
}
public bool RuleMatches(TilingRule rule, ref TileBase[] neighboringTiles, int angle)
{
for (var i = 0; i < NeighborCount; ++i)
{
var index = GetRotatedIndex(i, angle);
var tile = neighboringTiles[index];
if (rule.m_Neighbors[i] == TilingRule.Neighbor.This && tile != m_Self ||
rule.m_Neighbors[i] == TilingRule.Neighbor.NotThis && tile == m_Self)
{
return false;
}
}
return true;
}
public bool RuleMatches(TilingRule rule, ref TileBase[] neighboringTiles, bool mirrorX, bool mirrorY)
{
for (var i = 0; i < NeighborCount; ++i)
{
var index = GetMirroredIndex(i, mirrorX, mirrorY);
var tile = neighboringTiles[index];
if (rule.m_Neighbors[i] == TilingRule.Neighbor.This && tile != m_Self ||
rule.m_Neighbors[i] == TilingRule.Neighbor.NotThis && tile == m_Self)
{
return false;
}
}
return true;
}
private void GetMatchingNeighboringTiles(ITilemap tilemap, Vector3Int position, ref TileBase[] neighboringTiles)
{
if (neighboringTiles != null)
{
return;
}
if (m_CachedNeighboringTiles == null || m_CachedNeighboringTiles.Length < NeighborCount)
{
m_CachedNeighboringTiles = new TileBase[NeighborCount];
}
var index = 0;
for (var y = 1; y >= -1; y--)
for (var x = -1; x <= 1; x++)
{
if (x != 0 || y != 0)
{
var tilePosition = new Vector3Int(position.x + x, position.y + y, position.z);
m_CachedNeighboringTiles[index++] = tilemap.GetTile(tilePosition);
}
}
neighboringTiles = m_CachedNeighboringTiles;
}
private int GetRotatedIndex(int original, int rotation)
{
switch (rotation)
{
case 0:
return original;
case 90:
return RotatedOrMirroredIndexes[0, original];
case 180:
return RotatedOrMirroredIndexes[1, original];
case 270:
return RotatedOrMirroredIndexes[2, original];
}
return original;
}
private int GetMirroredIndex(int original, bool mirrorX, bool mirrorY)
{
if (mirrorX && mirrorY)
{
return RotatedOrMirroredIndexes[1, original];
}
if (mirrorX)
{
return RotatedOrMirroredIndexes[3, original];
}
if (mirrorY)
{
return RotatedOrMirroredIndexes[4, original];
}
return original;
}
private int GetIndexOfOffset(Vector3Int offset)
{
var result = offset.x + 1 + (-offset.y + 1) * 3;
if (result >= 4)
{
result--;
}
return result;
}
public Vector3Int GetRotatedPos(Vector3Int original, int rotation)
{
switch (rotation)
{
case 0:
return original;
case 90:
return new Vector3Int(-original.y, original.x, original.z);
case 180:
return new Vector3Int(-original.x, -original.y, original.z);
case 270:
return new Vector3Int(original.y, -original.x, original.z);
}
return original;
}
public Vector3Int GetMirroredPos(Vector3Int original, bool mirrorX, bool mirrorY)
{
return new Vector3Int(original.x * (mirrorX ? -1 : 1), original.y * (mirrorY ? -1 : 1), original.z);
}
[Serializable]
public class TilingRule
{
public enum Neighbor { DontCare, This, NotThis }
public enum OutputSprite { Single, Random, Animation }
public enum Transform { Fixed, Rotated, MirrorX, MirrorY }
public float m_AnimationSpeed;
public Tile.ColliderType m_ColliderType;
public Neighbor[] m_Neighbors;
public OutputSprite m_Output;
public float m_PerlinScale;
public Transform m_RandomTransform;
public Transform m_RuleTransform;
public Sprite[] m_Sprites;
public TilingRule()
{
m_Output = OutputSprite.Single;
m_Neighbors = new Neighbor[NeighborCount];
m_Sprites = new Sprite[1];
m_AnimationSpeed = 1f;
m_PerlinScale = 0.5f;
m_ColliderType = Tile.ColliderType.Sprite;
for (var i = 0; i < m_Neighbors.Length; i++)
{
m_Neighbors[i] = Neighbor.DontCare;
}
}
}
}
}

View file

@ -0,0 +1,13 @@
fileFormatVersion: 2
guid: 9d1514134bc4fbd41bb739b1b9a49231
timeCreated: 1501789622
licenseType: Pro
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View file

@ -0,0 +1,10 @@
fileFormatVersion: 2
guid: 7f83a174d475ee842aaea9ee552fa506
folderAsset: yes
timeCreated: 1499149439
licenseType: Pro
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View file

@ -0,0 +1,10 @@
fileFormatVersion: 2
guid: 14fc4c2dd67018d41b00db847f45f5dd
folderAsset: yes
timeCreated: 1499149468
licenseType: Pro
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View file

@ -0,0 +1,261 @@
using System;
#if UNITY_EDITOR
using UnityEditor;
#endif
namespace UnityEngine.Tilemaps
{
[Serializable]
public class TerrainTile : TileBase
{
[SerializeField] public Sprite[] m_Sprites;
public override void RefreshTile(Vector3Int location, ITilemap tileMap)
{
for (var yd = -1; yd <= 1; yd++)
for (var xd = -1; xd <= 1; xd++)
{
var position = new Vector3Int(location.x + xd, location.y + yd, location.z);
if (TileValue(tileMap, position))
{
tileMap.RefreshTile(position);
}
}
}
public override void GetTileData(Vector3Int location, ITilemap tileMap, ref TileData tileData)
{
UpdateTile(location, tileMap, ref tileData);
}
private void UpdateTile(Vector3Int location, ITilemap tileMap, ref TileData tileData)
{
tileData.transform = Matrix4x4.identity;
tileData.color = Color.white;
var mask = TileValue(tileMap, location + new Vector3Int(0, 1, 0)) ? 1 : 0;
mask += TileValue(tileMap, location + new Vector3Int(1, 1, 0)) ? 2 : 0;
mask += TileValue(tileMap, location + new Vector3Int(1, 0, 0)) ? 4 : 0;
mask += TileValue(tileMap, location + new Vector3Int(1, -1, 0)) ? 8 : 0;
mask += TileValue(tileMap, location + new Vector3Int(0, -1, 0)) ? 16 : 0;
mask += TileValue(tileMap, location + new Vector3Int(-1, -1, 0)) ? 32 : 0;
mask += TileValue(tileMap, location + new Vector3Int(-1, 0, 0)) ? 64 : 0;
mask += TileValue(tileMap, location + new Vector3Int(-1, 1, 0)) ? 128 : 0;
var original = (byte)mask;
if ((original | 254) < 255)
{
mask = mask & 125;
}
if ((original | 251) < 255)
{
mask = mask & 245;
}
if ((original | 239) < 255)
{
mask = mask & 215;
}
if ((original | 191) < 255)
{
mask = mask & 95;
}
var index = GetIndex((byte)mask);
if (index >= 0 && index < m_Sprites.Length && TileValue(tileMap, location))
{
tileData.sprite = m_Sprites[index];
tileData.transform = GetTransform((byte)mask);
tileData.color = Color.white;
tileData.flags = TileFlags.LockTransform | TileFlags.LockColor;
tileData.colliderType = Tile.ColliderType.Sprite;
}
}
private bool TileValue(ITilemap tileMap, Vector3Int position)
{
var tile = tileMap.GetTile(position);
return tile != null && tile == this;
}
private int GetIndex(byte mask)
{
switch (mask)
{
case 0: return 0;
case 1:
case 4:
case 16:
case 64: return 1;
case 5:
case 20:
case 80:
case 65: return 2;
case 7:
case 28:
case 112:
case 193: return 3;
case 17:
case 68: return 4;
case 21:
case 84:
case 81:
case 69: return 5;
case 23:
case 92:
case 113:
case 197: return 6;
case 29:
case 116:
case 209:
case 71: return 7;
case 31:
case 124:
case 241:
case 199: return 8;
case 85: return 9;
case 87:
case 93:
case 117:
case 213: return 10;
case 95:
case 125:
case 245:
case 215: return 11;
case 119:
case 221: return 12;
case 127:
case 253:
case 247:
case 223: return 13;
case 255: return 14;
}
return -1;
}
private Matrix4x4 GetTransform(byte mask)
{
switch (mask)
{
case 4:
case 20:
case 28:
case 68:
case 84:
case 92:
case 116:
case 124:
case 93:
case 125:
case 221:
case 253:
return Matrix4x4.TRS(Vector3.zero, Quaternion.Euler(0f, 0f, -90f), Vector3.one);
case 16:
case 80:
case 112:
case 81:
case 113:
case 209:
case 241:
case 117:
case 245:
case 247:
return Matrix4x4.TRS(Vector3.zero, Quaternion.Euler(0f, 0f, -180f), Vector3.one);
case 64:
case 65:
case 193:
case 69:
case 197:
case 71:
case 199:
case 213:
case 215:
case 223:
return Matrix4x4.TRS(Vector3.zero, Quaternion.Euler(0f, 0f, -270f), Vector3.one);
}
return Matrix4x4.identity;
}
#if UNITY_EDITOR
[MenuItem("Assets/Create/Terrain Tile")]
public static void CreateTerrainTile()
{
var path = EditorUtility.SaveFilePanelInProject("Save Terrain Tile", "New Terrain Tile", "asset", "Save Terrain Tile", "Assets");
if (path == "")
{
return;
}
AssetDatabase.CreateAsset(CreateInstance<TerrainTile>(), path);
}
#endif
}
#if UNITY_EDITOR
[CustomEditor(typeof(TerrainTile))]
public class TerrainTileEditor : Editor
{
private TerrainTile tile => target as TerrainTile;
public void OnEnable()
{
if (tile.m_Sprites == null || tile.m_Sprites.Length != 15)
{
tile.m_Sprites = new Sprite[15];
EditorUtility.SetDirty(tile);
}
}
public override void OnInspectorGUI()
{
EditorGUILayout.LabelField("Place sprites shown based on the contents of the sprite.");
EditorGUILayout.Space();
var oldLabelWidth = EditorGUIUtility.labelWidth;
EditorGUIUtility.labelWidth = 210;
EditorGUI.BeginChangeCheck();
tile.m_Sprites[0] = (Sprite)EditorGUILayout.ObjectField("Filled", tile.m_Sprites[0], typeof(Sprite), false, null);
tile.m_Sprites[1] = (Sprite)EditorGUILayout.ObjectField("Three Sides", tile.m_Sprites[1], typeof(Sprite), false, null);
tile.m_Sprites[2] = (Sprite)EditorGUILayout.ObjectField("Two Sides and One Corner", tile.m_Sprites[2], typeof(Sprite), false, null);
tile.m_Sprites[3] = (Sprite)EditorGUILayout.ObjectField("Two Adjacent Sides", tile.m_Sprites[3], typeof(Sprite), false, null);
tile.m_Sprites[4] = (Sprite)EditorGUILayout.ObjectField("Two Opposite Sides", tile.m_Sprites[4], typeof(Sprite), false, null);
tile.m_Sprites[5] = (Sprite)EditorGUILayout.ObjectField("One Side and Two Corners", tile.m_Sprites[5], typeof(Sprite), false, null);
tile.m_Sprites[6] = (Sprite)EditorGUILayout.ObjectField("One Side and One Lower Corner", tile.m_Sprites[6], typeof(Sprite), false, null);
tile.m_Sprites[7] = (Sprite)EditorGUILayout.ObjectField("One Side and One Upper Corner", tile.m_Sprites[7], typeof(Sprite), false, null);
tile.m_Sprites[8] = (Sprite)EditorGUILayout.ObjectField("One Side", tile.m_Sprites[8], typeof(Sprite), false, null);
tile.m_Sprites[9] = (Sprite)EditorGUILayout.ObjectField("Four Corners", tile.m_Sprites[9], typeof(Sprite), false, null);
tile.m_Sprites[10] = (Sprite)EditorGUILayout.ObjectField("Three Corners", tile.m_Sprites[10], typeof(Sprite), false, null);
tile.m_Sprites[11] = (Sprite)EditorGUILayout.ObjectField("Two Adjacent Corners", tile.m_Sprites[11], typeof(Sprite), false, null);
tile.m_Sprites[12] = (Sprite)EditorGUILayout.ObjectField("Two Opposite Corners", tile.m_Sprites[12], typeof(Sprite), false, null);
tile.m_Sprites[13] = (Sprite)EditorGUILayout.ObjectField("One Corner", tile.m_Sprites[13], typeof(Sprite), false, null);
tile.m_Sprites[14] = (Sprite)EditorGUILayout.ObjectField("Empty", tile.m_Sprites[14], typeof(Sprite), false, null);
if (EditorGUI.EndChangeCheck())
{
EditorUtility.SetDirty(tile);
}
EditorGUIUtility.labelWidth = oldLabelWidth;
}
}
#endif
}

View file

@ -0,0 +1,12 @@
fileFormatVersion: 2
guid: f6e4e4fc705376343a3e65b25d94f0e2
timeCreated: 1464534739
licenseType: Pro
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View file

@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 4ec81e1e269ae1d4787784bf0e950f5f
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View file

@ -0,0 +1,125 @@
using System;
#if UNITY_EDITOR
using UnityEditor;
#endif
namespace UnityEngine.Tilemaps
{
[Serializable]
public struct WeightedSprite
{
public Sprite Sprite;
public int Weight;
}
[Serializable]
public class WeightedRandomTile : Tile
{
[SerializeField] public WeightedSprite[] Sprites;
public override void GetTileData(Vector3Int location, ITilemap tileMap, ref TileData tileData)
{
base.GetTileData(location, tileMap, ref tileData);
if (Sprites == null || Sprites.Length <= 0)
{
return;
}
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);
// Get the cumulative weight of the sprites
var cumulativeWeight = 0;
foreach (var spriteInfo in Sprites)
{
cumulativeWeight += spriteInfo.Weight;
}
// Pick a random weight and choose a sprite depending on it
var randomWeight = Random.Range(0, cumulativeWeight);
foreach (var spriteInfo in Sprites)
{
randomWeight -= spriteInfo.Weight;
if (randomWeight < 0)
{
tileData.sprite = spriteInfo.Sprite;
break;
}
}
}
#if UNITY_EDITOR
[MenuItem("Assets/Create/Weighted Random Tile")]
public static void CreateRandomTile()
{
var path = EditorUtility.SaveFilePanelInProject(
"Save Weighted Random Tile",
"New Weighted Random Tile",
"asset",
"Save Weighted Random Tile",
"Assets");
if (path == "")
{
return;
}
AssetDatabase.CreateAsset(CreateInstance<WeightedRandomTile>(), path);
}
#endif
}
#if UNITY_EDITOR
[CustomEditor(typeof(WeightedRandomTile))]
public class WeightedRandomTileEditor : Editor
{
private WeightedRandomTile Tile => target as WeightedRandomTile;
public override void OnInspectorGUI()
{
EditorGUI.BeginChangeCheck();
var count = EditorGUILayout.DelayedIntField("Number of Sprites", Tile.Sprites != null ? Tile.Sprites.Length : 0);
if (count < 0)
{
count = 0;
}
if (Tile.Sprites == null || Tile.Sprites.Length != count)
{
Array.Resize(ref Tile.Sprites, count);
}
if (count == 0)
{
return;
}
EditorGUILayout.LabelField("Place random sprites.");
EditorGUILayout.Space();
for (var i = 0; i < count; i++)
{
Tile.Sprites[i].Sprite = (Sprite)EditorGUILayout.ObjectField(
"Sprite " + (i + 1),
Tile.Sprites[i].Sprite,
typeof(Sprite),
false,
null);
Tile.Sprites[i].Weight = EditorGUILayout.IntField("Weight " + (i + 1), Tile.Sprites[i].Weight);
}
if (EditorGUI.EndChangeCheck())
{
EditorUtility.SetDirty(Tile);
}
}
}
#endif
}

View file

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 1b859987a0026e2498a93cc8109d5b55
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant: