Нет описания
Вы не можете выбрать более 25 тем Темы должны начинаться с буквы или цифры, могут содержать дефисы(-) и должны содержать не более 35 символов.

AdvancedRuleOverrideTileEditor.cs 9.3KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215
  1. using UnityEngine;
  2. using UnityEngine.Tilemaps;
  3. using UnityEditorInternal;
  4. using System.Collections.Generic;
  5. namespace UnityEditor
  6. {
  7. /// <summary>
  8. /// The Editor for an AdvancedRuleOverrideTileEditor.
  9. /// </summary>
  10. [CustomEditor(typeof(AdvancedRuleOverrideTile))]
  11. public class AdvancedRuleOverrideTileEditor : RuleOverrideTileEditor
  12. {
  13. private static class Styles
  14. {
  15. public static readonly GUIContent defaultSprite = EditorGUIUtility.TrTextContent("Default Sprite"
  16. , "Overrides the default Sprite for the original Rule Tile.");
  17. public static readonly GUIContent defaultGameObject = EditorGUIUtility.TrTextContent("Default GameObject"
  18. , "Overrides the default GameObject for the original Rule Tile.");
  19. public static readonly GUIContent defaultCollider = EditorGUIUtility.TrTextContent("Default Collider"
  20. , "Overrides the default Collider for the original Rule Tile.");
  21. }
  22. /// <summary>
  23. /// The AdvancedRuleOverrideTile being edited.
  24. /// </summary>
  25. public new AdvancedRuleOverrideTile overrideTile => target as AdvancedRuleOverrideTile;
  26. List<KeyValuePair<RuleTile.TilingRule, RuleTile.TilingRuleOutput>> m_Rules = new List<KeyValuePair<RuleTile.TilingRule, RuleTile.TilingRuleOutput>>();
  27. private ReorderableList m_RuleList;
  28. private int m_MissingOriginalRuleIndex;
  29. private HashSet<int> m_UniqueIds = new HashSet<int>();
  30. static float k_DefaultElementHeight { get { return RuleTileEditor.k_DefaultElementHeight; } }
  31. static float k_SingleLineHeight { get { return RuleTileEditor.k_SingleLineHeight; } }
  32. /// <summary>
  33. /// OnEnable for the AdvancedRuleOverrideTileEditor
  34. /// </summary>
  35. public override void OnEnable()
  36. {
  37. if (m_RuleList == null)
  38. {
  39. m_RuleList = new ReorderableList(m_Rules, typeof(KeyValuePair<RuleTile.TilingRule, RuleTile.TilingRule>), false, true, false, false);
  40. m_RuleList.drawHeaderCallback = DrawRulesHeader;
  41. m_RuleList.drawElementCallback = DrawRuleElement;
  42. m_RuleList.elementHeightCallback = GetRuleElementHeight;
  43. }
  44. }
  45. /// <summary>
  46. /// Draws the Inspector GUI for the AdvancedRuleOverrideTileEditor
  47. /// </summary>
  48. public override void OnInspectorGUI()
  49. {
  50. serializedObject.UpdateIfRequiredOrScript();
  51. DrawTileField();
  52. EditorGUI.BeginChangeCheck();
  53. overrideTile.m_DefaultSprite = EditorGUILayout.ObjectField(Styles.defaultSprite, overrideTile.m_DefaultSprite, typeof(Sprite), false) as Sprite;
  54. overrideTile.m_DefaultGameObject = EditorGUILayout.ObjectField(Styles.defaultGameObject, overrideTile.m_DefaultGameObject, typeof(GameObject), false) as GameObject;
  55. overrideTile.m_DefaultColliderType = (Tile.ColliderType)EditorGUILayout.EnumPopup(Styles.defaultCollider, overrideTile.m_DefaultColliderType);
  56. if (EditorGUI.EndChangeCheck())
  57. SaveTile();
  58. DrawCustomFields();
  59. if (overrideTile.m_Tile)
  60. {
  61. ValidateRuleTile(overrideTile.m_Tile);
  62. overrideTile.GetOverrides(m_Rules, ref m_MissingOriginalRuleIndex);
  63. }
  64. m_RuleList.DoLayoutList();
  65. }
  66. private void ValidateRuleTile(RuleTile ruleTile)
  67. {
  68. // Ensure that each Tiling Rule in the RuleTile has a unique ID
  69. m_UniqueIds.Clear();
  70. var startId = 0;
  71. foreach (var rule in ruleTile.m_TilingRules)
  72. {
  73. if (m_UniqueIds.Contains(rule.m_Id))
  74. {
  75. do
  76. {
  77. rule.m_Id = startId++;
  78. } while (m_UniqueIds.Contains(rule.m_Id));
  79. EditorUtility.SetDirty(ruleTile);
  80. }
  81. m_UniqueIds.Add(rule.m_Id);
  82. startId++;
  83. }
  84. }
  85. /// <summary>
  86. /// Draws the Header for the Rule list
  87. /// </summary>
  88. /// <param name="rect">Rect to draw the header in</param>
  89. public void DrawRulesHeader(Rect rect)
  90. {
  91. GUI.Label(rect, "Tiling Rules", EditorStyles.label);
  92. }
  93. /// <summary>
  94. /// Draws the Rule element for the Rule list
  95. /// </summary>
  96. /// <param name="rect">Rect to draw the Rule Element in</param>
  97. /// <param name="index">Index of the Rule Element to draw</param>
  98. /// <param name="active">Whether the Rule Element is active</param>
  99. /// <param name="focused">Whether the Rule Element is focused</param>
  100. public void DrawRuleElement(Rect rect, int index, bool active, bool focused)
  101. {
  102. RuleTile.TilingRule originalRule = m_Rules[index].Key;
  103. if (originalRule == null)
  104. return;
  105. RuleTile.TilingRuleOutput overrideRule = m_Rules[index].Value;
  106. bool isMissing = index >= m_MissingOriginalRuleIndex;
  107. DrawToggleInternal(new Rect(rect.xMin, rect.yMin, 16, rect.height));
  108. DrawRuleInternal(new Rect(rect.xMin + 16, rect.yMin, rect.width - 16, rect.height));
  109. void DrawToggleInternal(Rect r)
  110. {
  111. EditorGUI.BeginChangeCheck();
  112. bool enabled = EditorGUI.Toggle(new Rect(r.xMin, r.yMin, r.width, k_SingleLineHeight), overrideRule != null);
  113. if (EditorGUI.EndChangeCheck())
  114. {
  115. if (enabled)
  116. overrideTile[originalRule] = originalRule;
  117. else
  118. overrideTile[originalRule] = null;
  119. SaveTile();
  120. }
  121. }
  122. void DrawRuleInternal(Rect r)
  123. {
  124. EditorGUI.BeginChangeCheck();
  125. DrawRule(r, overrideRule ?? originalRule, overrideRule != null, originalRule, isMissing);
  126. if (EditorGUI.EndChangeCheck())
  127. SaveTile();
  128. }
  129. }
  130. /// <summary>
  131. /// Draw a Rule Override for the AdvancedRuleOverrideTileEditor
  132. /// </summary>
  133. /// <param name="rect">Rect to draw the Rule in</param>
  134. /// <param name="rule">The Rule Override to draw</param>
  135. /// <param name="isOverride">Whether the original Rule is being overridden</param>
  136. /// <param name="originalRule">Original Rule to override</param>
  137. /// <param name="isMissing">Whether the original Rule is missing</param>
  138. public void DrawRule(Rect rect, RuleTile.TilingRuleOutput rule, bool isOverride, RuleTile.TilingRule originalRule, bool isMissing)
  139. {
  140. if (isMissing)
  141. {
  142. EditorGUI.HelpBox(new Rect(rect.xMin, rect.yMin, rect.width, 16), "Original Tiling Rule missing", MessageType.Warning);
  143. rect.yMin += 16;
  144. }
  145. using (new EditorGUI.DisabledScope(!isOverride))
  146. {
  147. float yPos = rect.yMin + 2f;
  148. float height = rect.height - k_PaddingBetweenRules;
  149. float matrixWidth = k_DefaultElementHeight;
  150. BoundsInt ruleBounds = originalRule.GetBounds();
  151. BoundsInt ruleGuiBounds = ruleTileEditor.GetRuleGUIBounds(ruleBounds, originalRule);
  152. Vector2 matrixSize = ruleTileEditor.GetMatrixSize(ruleGuiBounds);
  153. Vector2 matrixSizeRate = matrixSize / Mathf.Max(matrixSize.x, matrixSize.y);
  154. Vector2 matrixRectSize = new Vector2(matrixWidth * matrixSizeRate.x, k_DefaultElementHeight * matrixSizeRate.y);
  155. Vector2 matrixRectPosition = new Vector2(rect.xMax - matrixWidth * 2f - 10f, yPos);
  156. matrixRectPosition.x += (matrixWidth - matrixRectSize.x) * 0.5f;
  157. matrixRectPosition.y += (k_DefaultElementHeight - matrixRectSize.y) * 0.5f;
  158. Rect inspectorRect = new Rect(rect.xMin, yPos, rect.width - matrixWidth * 2f - 20f, height);
  159. Rect matrixRect = new Rect(matrixRectPosition, matrixRectSize);
  160. Rect spriteRect = new Rect(rect.xMax - matrixWidth - 5f, yPos, matrixWidth, k_DefaultElementHeight);
  161. ruleTileEditor.RuleInspectorOnGUI(inspectorRect, rule);
  162. ruleTileEditor.SpriteOnGUI(spriteRect, rule);
  163. if (!isMissing)
  164. using (new EditorGUI.DisabledScope(true))
  165. ruleTileEditor.RuleMatrixOnGUI(overrideTile.m_InstanceTile, matrixRect, ruleGuiBounds, originalRule);
  166. }
  167. }
  168. /// <summary>
  169. /// Returns the height for an indexed Rule Element
  170. /// </summary>
  171. /// <param name="index">Index of the Rule Element</param>
  172. /// <returns>Height of the indexed Rule Element</returns>
  173. public float GetRuleElementHeight(int index)
  174. {
  175. var originalRule = m_Rules[index].Key;
  176. var overrideRule = m_Rules[index].Value;
  177. float height = overrideRule != null ? ruleTileEditor.GetElementHeight(overrideRule) : ruleTileEditor.GetElementHeight(originalRule);
  178. bool isMissing = index >= m_MissingOriginalRuleIndex;
  179. if (isMissing)
  180. height += 16;
  181. return height;
  182. }
  183. }
  184. }