Skip to content

Commit

Permalink
-Fix undo when setting number of Sprites for Animated Tile and number…
Browse files Browse the repository at this point in the history
… of Rules for Rule Tile (Unity-Technologies#317)

* -Fix undo when setting number of Sprites for Animated Tile and number of Rules for Rule Tile

* -Initialise TilingRules when changing array size from 0 to other values

* -Use Resize when adding new items from the ReorderableList

* -Ensure TilingRule Ids are updated when TilingRules are added

* -Add new element after selection
  • Loading branch information
ChuanXin-Unity authored Jan 14, 2022
1 parent a4096eb commit 5e0d066
Show file tree
Hide file tree
Showing 2 changed files with 92 additions and 44 deletions.
101 changes: 65 additions & 36 deletions Editor/Tiles/RuleTile/RuleTileEditor.cs
Original file line number Diff line number Diff line change
Expand Up @@ -177,6 +177,8 @@ private static class Styles
/// </summary>
public const float k_LabelWidth = 80f;

private SerializedProperty m_TilingRules;

/// <summary>
/// OnEnable for the RuleTileEditor
/// </summary>
Expand All @@ -188,6 +190,8 @@ public virtual void OnEnable()
m_ReorderableList.elementHeightCallback = GetElementHeight;
m_ReorderableList.onChangedCallback = ListUpdated;
m_ReorderableList.onAddDropdownCallback = OnAddDropdownElement;

m_TilingRules = serializedObject.FindProperty("m_TilingRules");
}

/// <summary>
Expand All @@ -198,6 +202,17 @@ public virtual void OnDisable()
DestroyPreview();
}

private void UpdateTilingRuleIds()
{
HashSet<int> usedIdSet = new HashSet<int>();
foreach (var rule in tile.m_TilingRules)
{
while (usedIdSet.Contains(rule.m_Id))
rule.m_Id++;
usedIdSet.Add(rule.m_Id);
}
}

/// <summary>
/// Get the GUI bounds for a Rule.
/// </summary>
Expand Down Expand Up @@ -226,13 +241,7 @@ public virtual BoundsInt GetRuleGUIBounds(BoundsInt bounds, RuleTile.TilingRule
/// <param name="list">Reorderable list for Rules</param>
public void ListUpdated(ReorderableList list)
{
HashSet<int> usedIdSet = new HashSet<int>();
foreach (var rule in tile.m_TilingRules)
{
while (usedIdSet.Contains(rule.m_Id))
rule.m_Id++;
usedIdSet.Add(rule.m_Id);
}
UpdateTilingRuleIds();
}

private float GetElementHeight(int index)
Expand Down Expand Up @@ -267,8 +276,8 @@ public float GetElementHeight(RuleTile.TilingRuleOutput rule)

switch (rule.m_Output)
{
case RuleTile.TilingRule.OutputSprite.Random:
case RuleTile.TilingRule.OutputSprite.Animation:
case RuleTile.TilingRuleOutput.OutputSprite.Random:
case RuleTile.TilingRuleOutput.OutputSprite.Animation:
inspectorHeight = k_DefaultElementHeight + k_SingleLineHeight * (rule.m_Sprites.Length + 3) + k_PaddingBetweenRules;
break;
}
Expand Down Expand Up @@ -315,18 +324,24 @@ private void OnAddElement(object obj)
{
var list = obj as ReorderableList;
RuleTile.TilingRule rule = new RuleTile.TilingRule();
rule.m_Output = RuleTile.TilingRule.OutputSprite.Single;
rule.m_Output = RuleTile.TilingRuleOutput.OutputSprite.Single;
rule.m_Sprites[0] = tile.m_DefaultSprite;
rule.m_GameObject = tile.m_DefaultGameObject;
rule.m_ColliderType = tile.m_DefaultColliderType;

var count = m_TilingRules.arraySize;
ResizeRuleTileList(count + 1);

if (list.index == -1 || list.index >= list.count)
tile.m_TilingRules.Add(rule);
tile.m_TilingRules[count] = rule;
else
{
tile.m_TilingRules.Insert(list.index + 1, rule);
tile.m_TilingRules.RemoveAt(count + 1);
if (list.IsSelected(list.index))
list.index += 1;
}
UpdateTilingRuleIds();
}

private void OnDuplicateElement(object obj)
Expand All @@ -337,9 +352,15 @@ private void OnDuplicateElement(object obj)

var copyRule = tile.m_TilingRules[list.index];
var rule = copyRule.Clone();

var count = m_TilingRules.arraySize;
ResizeRuleTileList(count + 1);

tile.m_TilingRules.Insert(list.index + 1, rule);
tile.m_TilingRules.RemoveAt(count + 1);
if (list.IsSelected(list.index))
list.index += 1;
UpdateTilingRuleIds();
}

private void OnAddDropdownElement(Rect rect, ReorderableList list)
Expand All @@ -362,6 +383,7 @@ private void OnAddDropdownElement(Rect rect, ReorderableList list)
/// </summary>
public void SaveTile()
{
serializedObject.ApplyModifiedProperties();
EditorUtility.SetDirty(target);
SceneView.RepaintAll();

Expand Down Expand Up @@ -446,6 +468,7 @@ public void OnDrawHeader(Rect rect)
/// </summary>
public override void OnInspectorGUI()
{
serializedObject.Update();
Undo.RecordObject(target, k_UndoName);

EditorGUI.BeginChangeCheck();
Expand Down Expand Up @@ -484,18 +507,24 @@ public override void OnInspectorGUI()

if (EditorGUI.EndChangeCheck())
SaveTile();

GUILayout.Space(k_DefaultElementHeight);
}

private void ResizeRuleTileList(int count)
{
if (tile.m_TilingRules == null)
tile.m_TilingRules = new List<RuleTile.TilingRule>();
while (tile.m_TilingRules.Count > count)
tile.m_TilingRules.RemoveAt(tile.m_TilingRules.Count - 1);
while (tile.m_TilingRules.Count < count)
tile.m_TilingRules.Add(new RuleTile.TilingRule());
if (m_TilingRules.arraySize == count)
return;

var isEmpty = m_TilingRules.arraySize == 0;
m_TilingRules.arraySize = count;
serializedObject.ApplyModifiedProperties();
if (isEmpty)
{
for (int i = 0; i < count; ++i)
tile.m_TilingRules[i] = new RuleTile.TilingRule();
}
UpdateTilingRuleIds();
}

/// <summary>
Expand Down Expand Up @@ -569,10 +598,10 @@ public virtual void RuleOnGUI(Rect rect, Vector3Int position, int neighbor)
{
switch (neighbor)
{
case RuleTile.TilingRule.Neighbor.This:
case RuleTile.TilingRuleOutput.Neighbor.This:
GUI.DrawTexture(rect, arrows[GetArrowIndex(position)]);
break;
case RuleTile.TilingRule.Neighbor.NotThis:
case RuleTile.TilingRuleOutput.Neighbor.NotThis:
GUI.DrawTexture(rect, arrows[9]);
break;
default:
Expand All @@ -591,7 +620,7 @@ public virtual void RuleOnGUI(Rect rect, Vector3Int position, int neighbor)
/// <param name="neighbor">The index to the neighbor matching criteria</param>
public void RuleTooltipOnGUI(Rect rect, int neighbor)
{
var allConsts = tile.m_NeighborType.GetFields(System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.Static | System.Reflection.BindingFlags.FlattenHierarchy);
var allConsts = tile.m_NeighborType.GetFields(BindingFlags.Public | BindingFlags.Static | BindingFlags.FlattenHierarchy);
foreach (var c in allConsts)
{
if ((int)c.GetValue(null) == neighbor)
Expand All @@ -607,23 +636,23 @@ public void RuleTooltipOnGUI(Rect rect, int neighbor)
/// </summary>
/// <param name="rect">Rect to draw on</param>
/// <param name="ruleTransform">The transform matching criteria</param>
public virtual void RuleTransformOnGUI(Rect rect, RuleTile.TilingRule.Transform ruleTransform)
public virtual void RuleTransformOnGUI(Rect rect, RuleTile.TilingRuleOutput.Transform ruleTransform)
{
switch (ruleTransform)
{
case RuleTile.TilingRule.Transform.Rotated:
case RuleTile.TilingRuleOutput.Transform.Rotated:
GUI.DrawTexture(rect, autoTransforms[0]);
break;
case RuleTile.TilingRule.Transform.MirrorX:
case RuleTile.TilingRuleOutput.Transform.MirrorX:
GUI.DrawTexture(rect, autoTransforms[1]);
break;
case RuleTile.TilingRule.Transform.MirrorY:
case RuleTile.TilingRuleOutput.Transform.MirrorY:
GUI.DrawTexture(rect, autoTransforms[2]);
break;
case RuleTile.TilingRule.Transform.Fixed:
case RuleTile.TilingRuleOutput.Transform.Fixed:
GUI.DrawTexture(rect, autoTransforms[3]);
break;
case RuleTile.TilingRule.Transform.MirrorXY:
case RuleTile.TilingRuleOutput.Transform.MirrorXY:
GUI.DrawTexture(rect, autoTransforms[4]);
break;
}
Expand Down Expand Up @@ -679,7 +708,7 @@ public void RuleTransformUpdate(Rect rect, RuleTile.TilingRule tilingRule)
{
if (Event.current.type == EventType.MouseDown && ContainsMousePosition(rect))
{
tilingRule.m_RuleTransform = (RuleTile.TilingRule.Transform)(int)Mathf.Repeat((int)tilingRule.m_RuleTransform + GetMouseChange(), Enum.GetValues(typeof(RuleTile.TilingRule.Transform)).Length);
tilingRule.m_RuleTransform = (RuleTile.TilingRuleOutput.Transform)(int)Mathf.Repeat((int)tilingRule.m_RuleTransform + GetMouseChange(), Enum.GetValues(typeof(RuleTile.TilingRule.Transform)).Length);
GUI.changed = true;
Event.current.Use();
}
Expand Down Expand Up @@ -799,10 +828,10 @@ public void RuleInspectorOnGUI(Rect rect, RuleTile.TilingRuleOutput tilingRule)
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), Styles.tilingRulesOutput);
tilingRule.m_Output = (RuleTile.TilingRule.OutputSprite)EditorGUI.EnumPopup(new Rect(rect.xMin + k_LabelWidth, y, rect.width - k_LabelWidth, k_SingleLineHeight), tilingRule.m_Output);
tilingRule.m_Output = (RuleTile.TilingRuleOutput.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)
if (tilingRule.m_Output == RuleTile.TilingRuleOutput.OutputSprite.Animation)
{
GUI.Label(new Rect(rect.xMin, y, k_LabelWidth, k_SingleLineHeight), Styles.tilingRulesMinSpeed);
tilingRule.m_MinAnimationSpeed = EditorGUI.FloatField(new Rect(rect.xMin + k_LabelWidth, y, rect.width - k_LabelWidth, k_SingleLineHeight), tilingRule.m_MinAnimationSpeed);
Expand All @@ -811,18 +840,18 @@ public void RuleInspectorOnGUI(Rect rect, RuleTile.TilingRuleOutput tilingRule)
tilingRule.m_MaxAnimationSpeed = EditorGUI.FloatField(new Rect(rect.xMin + k_LabelWidth, y, rect.width - k_LabelWidth, k_SingleLineHeight), tilingRule.m_MaxAnimationSpeed);
y += k_SingleLineHeight;
}
if (tilingRule.m_Output == RuleTile.TilingRule.OutputSprite.Random)
if (tilingRule.m_Output == RuleTile.TilingRuleOutput.OutputSprite.Random)
{
GUI.Label(new Rect(rect.xMin, y, k_LabelWidth, k_SingleLineHeight), Styles.tilingRulesNoise);
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), Styles.tilingRulesShuffle);
tilingRule.m_RandomTransform = (RuleTile.TilingRule.Transform)EditorGUI.EnumPopup(new Rect(rect.xMin + k_LabelWidth, y, rect.width - k_LabelWidth, k_SingleLineHeight), tilingRule.m_RandomTransform);
tilingRule.m_RandomTransform = (RuleTile.TilingRuleOutput.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)
if (tilingRule.m_Output != RuleTile.TilingRuleOutput.OutputSprite.Single)
{
GUI.Label(new Rect(rect.xMin, y, k_LabelWidth, k_SingleLineHeight)
, tilingRule.m_Output == RuleTile.TilingRuleOutput.OutputSprite.Animation ? Styles.tilingRulesAnimationSize : Styles.tilingRulesRandomSize);
Expand Down Expand Up @@ -980,7 +1009,7 @@ public override void OnPreviewGUI(Rect rect, GUIStyle background)
m_PreviewUtility.BeginPreview(rect, background);
m_PreviewUtility.camera.orthographicSize = 2;
if (rect.height > rect.width)
m_PreviewUtility.camera.orthographicSize *= (float)rect.height / rect.width;
m_PreviewUtility.camera.orthographicSize *= rect.height / rect.width;
m_PreviewUtility.camera.Render();
m_PreviewUtility.EndAndDrawPreview(rect);
}
Expand Down Expand Up @@ -1054,7 +1083,7 @@ public override Texture2D RenderStaticPreview(string assetPath, Object[] subAsse
Type t = GetType("UnityEditor.SpriteUtility");
if (t != null)
{
MethodInfo method = t.GetMethod("RenderStaticPreview", new Type[] { typeof(Sprite), typeof(Color), typeof(int), typeof(int) });
MethodInfo method = t.GetMethod("RenderStaticPreview", new[] { 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 });
Expand Down Expand Up @@ -1096,7 +1125,7 @@ public static Texture2D Base64ToTexture(string base64)
{
Texture2D t = new Texture2D(1, 1);
t.hideFlags = HideFlags.HideAndDontSave;
t.LoadImage(System.Convert.FromBase64String(base64));
t.LoadImage(Convert.FromBase64String(base64));
return t;
}

Expand Down
35 changes: 27 additions & 8 deletions Runtime/Tiles/AnimatedTile/AnimatedTile.cs
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,8 @@ private static class Styles
}

private static readonly string k_UndoName = L10n.Tr("Change AnimatedTile");

private SerializedProperty m_AnimatedSprites;

private AnimatedTile tile { get { return (target as AnimatedTile); } }

Expand All @@ -129,6 +131,8 @@ private void OnEnable()
reorderableList.onAddCallback = OnAddElement;
reorderableList.onRemoveCallback = OnRemoveElement;
reorderableList.onReorderCallback = OnReorderElement;

m_AnimatedSprites = serializedObject.FindProperty("m_AnimatedSprites");
}

private void OnDrawHeader(Rect rect)
Expand Down Expand Up @@ -157,13 +161,19 @@ private float GetElementHeight(int index)

private void OnAddElement(ReorderableList list)
{
if (tile.m_AnimatedSprites == null)
var count = tile.m_AnimatedSprites != null ? tile.m_AnimatedSprites.Length + 1 : 1;
ResizeAnimatedSpriteList(count);

if (list.index == 0 || list.index < list.count)
{
tile.m_AnimatedSprites = new Sprite[1];
Array.Copy(tile.m_AnimatedSprites, list.index + 1, tile.m_AnimatedSprites, list.index + 2, list.count - list.index - 1);
tile.m_AnimatedSprites[list.index + 1] = null;
if (list.IsSelected(list.index))
list.index += 1;
}
else
{
Array.Resize<Sprite>(ref tile.m_AnimatedSprites, tile.m_AnimatedSprites.Length + 1);
tile.m_AnimatedSprites[count - 1] = null;
}
}

Expand Down Expand Up @@ -275,7 +285,7 @@ private void HandleDragAndDrop(Rect guiRect)
return;

Undo.RegisterCompleteObjectUndo(tile, "Drag and Drop to Animated Tile");
Array.Resize<Sprite>(ref tile.m_AnimatedSprites, dragAndDropSprites.Count);
ResizeAnimatedSpriteList(dragAndDropSprites.Count);
Array.Copy(dragAndDropSprites.ToArray(), tile.m_AnimatedSprites, dragAndDropSprites.Count);
DragAndDropClear();
GUI.changed = true;
Expand All @@ -300,17 +310,17 @@ private void HandleDragAndDrop(Rect guiRect)
/// </summary>
public override void OnInspectorGUI()
{
Undo.RecordObject(target, k_UndoName);
serializedObject.Update();

Undo.RecordObject(tile, k_UndoName);

EditorGUI.BeginChangeCheck();
int 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<Sprite>(ref tile.m_AnimatedSprites, count);
}
ResizeAnimatedSpriteList(count);

if (count == 0)
{
Expand Down Expand Up @@ -361,7 +371,16 @@ public override void OnInspectorGUI()
}

if (EditorGUI.EndChangeCheck())
{
serializedObject.ApplyModifiedProperties();
EditorUtility.SetDirty(tile);
}
}

private void ResizeAnimatedSpriteList(int count)
{
m_AnimatedSprites.arraySize = count;
serializedObject.ApplyModifiedProperties();
}
}
#endif
Expand Down

0 comments on commit 5e0d066

Please sign in to comment.