No Description
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

HexagonalRuleTileEditor.cs 8.6KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223
  1. using UnityEngine;
  2. using UnityEngine.Tilemaps;
  3. namespace UnityEditor
  4. {
  5. /// <summary>
  6. /// The Editor for a HexagonalRuleTile.
  7. /// </summary>
  8. [CustomEditor(typeof(HexagonalRuleTile), true)]
  9. [CanEditMultipleObjects]
  10. public class HexagonalRuleTileEditor : RuleTileEditor
  11. {
  12. /// <summary>
  13. /// The HexagonalRuleTile being edited.
  14. /// </summary>
  15. public HexagonalRuleTile hexTile => target as HexagonalRuleTile;
  16. /// <summary>
  17. /// Gets the index for a Rule with the HexagonalRuleTile to display an arrow.
  18. /// </summary>
  19. /// <param name="position">The adjacent position of the arrow.</param>
  20. /// <returns>Returns the index for a Rule with the HexagonalRuleTile to display an arrow.</returns>
  21. public override int GetArrowIndex(Vector3Int position)
  22. {
  23. if (position.y % 2 != 0)
  24. {
  25. position *= 2;
  26. position.x += 1;
  27. }
  28. if (position.x == 0)
  29. {
  30. if (position.y > 0)
  31. return hexTile.m_FlatTop ? 5 : 1;
  32. else
  33. return hexTile.m_FlatTop ? 3 : 7;
  34. }
  35. else if (position.y == 0)
  36. {
  37. if (position.x > 0)
  38. return hexTile.m_FlatTop ? 1 : 5;
  39. else
  40. return hexTile.m_FlatTop ? 7 : 3;
  41. }
  42. else
  43. {
  44. if (position.x < 0 && position.y > 0)
  45. return hexTile.m_FlatTop ? 8 : 0;
  46. else if (position.x > 0 && position.y > 0)
  47. return hexTile.m_FlatTop ? 2 : 2;
  48. else if (position.x < 0 && position.y < 0)
  49. return hexTile.m_FlatTop ? 6 : 6;
  50. else if (position.x > 0 && position.y < 0)
  51. return hexTile.m_FlatTop ? 0 : 8;
  52. }
  53. return -1;
  54. }
  55. /// <summary>
  56. /// Get the GUI bounds for a Rule.
  57. /// </summary>
  58. /// <param name="bounds">Cell bounds of the Rule.</param>
  59. /// <param name="rule">Rule to get GUI bounds for.</param>
  60. /// <returns>The GUI bounds for a rule.</returns>
  61. public override BoundsInt GetRuleGUIBounds(BoundsInt bounds, RuleTile.TilingRule rule)
  62. {
  63. foreach (var n in rule.GetNeighbors())
  64. {
  65. if (n.Key.x == bounds.xMax - 1 && n.Key.y % 2 != 0)
  66. {
  67. bounds.xMax++;
  68. break;
  69. }
  70. }
  71. return base.GetRuleGUIBounds(bounds, rule);
  72. }
  73. /// <summary>
  74. /// Gets the GUI matrix size for a Rule of a HexagonalRuleTile
  75. /// </summary>
  76. /// <param name="bounds">Cell bounds of the Rule.</param>
  77. /// <returns>Returns the GUI matrix size for a Rule of a HexagonalRuleTile.</returns>
  78. public override Vector2 GetMatrixSize(BoundsInt bounds)
  79. {
  80. Vector2 size = base.GetMatrixSize(bounds);
  81. return hexTile.m_FlatTop ? new Vector2(size.y, size.x) : size;
  82. }
  83. /// <summary>
  84. /// Draws a Rule Matrix for the given Rule for a HexagonalRuleTile.
  85. /// </summary>
  86. /// <param name="tile">Tile to draw rule for.</param>
  87. /// <param name="rect">GUI Rect to draw rule at.</param>
  88. /// <param name="bounds">Cell bounds of the Rule.</param>
  89. /// <param name="tilingRule">Rule to draw Rule Matrix for.</param>
  90. public override void RuleMatrixOnGUI(RuleTile tile, Rect rect, BoundsInt bounds, RuleTile.TilingRule tilingRule)
  91. {
  92. bool flatTop = hexTile.m_FlatTop;
  93. Handles.color = EditorGUIUtility.isProSkin ? new Color(1f, 1f, 1f, 0.2f) : new Color(0f, 0f, 0f, 0.2f);
  94. float w = rect.width / (flatTop ? bounds.size.y : bounds.size.x);
  95. float h = rect.height / (flatTop ? bounds.size.x : bounds.size.y);
  96. // Grid
  97. if (flatTop)
  98. {
  99. for (int y = 0; y <= bounds.size.y; y++)
  100. {
  101. float left = rect.xMin + y * w;
  102. float offset = 0;
  103. if (y == 0 && bounds.yMax % 2 == 0)
  104. offset = h / 2;
  105. else if (y == bounds.size.y && bounds.yMin % 2 != 0)
  106. offset = h / 2;
  107. Handles.DrawLine(new Vector3(left, rect.yMin + offset), new Vector3(left, rect.yMax - offset));
  108. if (y < bounds.size.y)
  109. {
  110. bool noOffset = (y + bounds.yMax) % 2 != 0;
  111. for (int x = 0; x < (noOffset ? (bounds.size.x + 1) : bounds.size.x); x++)
  112. {
  113. float top = rect.yMin + x * h + (noOffset ? 0 : h / 2);
  114. Handles.DrawLine(new Vector3(left, top), new Vector3(left + w, top));
  115. }
  116. }
  117. }
  118. }
  119. else
  120. {
  121. for (int y = 0; y <= bounds.size.y; y++)
  122. {
  123. float top = rect.yMin + y * h;
  124. float offset = 0;
  125. if (y == 0 && bounds.yMax % 2 == 0)
  126. offset = w / 2;
  127. else if (y == bounds.size.y && bounds.yMin % 2 != 0)
  128. offset = w / 2;
  129. Handles.DrawLine(new Vector3(rect.xMin + offset, top), new Vector3(rect.xMax - offset, top));
  130. if (y < bounds.size.y)
  131. {
  132. bool noOffset = (y + bounds.yMax) % 2 != 0;
  133. for (int x = 0; x < (noOffset ? (bounds.size.x + 1) : bounds.size.x); x++)
  134. {
  135. float left = rect.xMin + x * w + (noOffset ? 0 : w / 2);
  136. Handles.DrawLine(new Vector3(left, top), new Vector3(left, top + h));
  137. }
  138. }
  139. }
  140. }
  141. var neighbors = tilingRule.GetNeighbors();
  142. // Icons
  143. Handles.color = Color.white;
  144. for (int y = bounds.yMin; y < bounds.yMax; y++)
  145. {
  146. int xMax = y % 2 == 0 ? bounds.xMax : (bounds.xMax - 1);
  147. for (int x = bounds.xMin; x < xMax; x++)
  148. {
  149. Vector3Int pos = new Vector3Int(x, y, 0);
  150. Vector2 offset = new Vector2(x - bounds.xMin, -y + bounds.yMax - 1);
  151. Rect r = flatTop ? new Rect(rect.xMax - offset.y * w - w, rect.yMax - offset.x * h - h, w - 1, h - 1)
  152. : new Rect(rect.xMin + offset.x * w, rect.yMin + offset.y * h, w - 1, h - 1);
  153. if (y % 2 != 0)
  154. {
  155. if (flatTop)
  156. r.y -= h / 2;
  157. else
  158. r.x += w / 2;
  159. }
  160. RuleMatrixIconOnGUI(tilingRule, neighbors, pos, r);
  161. }
  162. }
  163. }
  164. /// <summary>
  165. /// Creates a Preview for the HexagonalRuleTile.
  166. /// </summary>
  167. protected override void CreatePreview()
  168. {
  169. base.CreatePreview();
  170. m_PreviewGrid.cellLayout = GridLayout.CellLayout.Hexagon;
  171. m_PreviewGrid.cellSize = new Vector3(0.8659766f, 1.0f, 1.0f);
  172. m_PreviewGrid.cellSwizzle = hexTile.m_FlatTop ? GridLayout.CellSwizzle.YXZ : GridLayout.CellSwizzle.XYZ;
  173. foreach (var tilemap in m_PreviewTilemaps)
  174. {
  175. tilemap.tileAnchor = Vector3.zero;
  176. tilemap.ClearAllTiles();
  177. }
  178. for (int x = -1; x <= 0; ++x)
  179. for (int y = -1; y <= 1; ++y)
  180. m_PreviewTilemaps[0].SetTile(new Vector3Int(x, y, 0), tile);
  181. m_PreviewTilemaps[1].SetTile(new Vector3Int(1, -1, 0), tile);
  182. m_PreviewTilemaps[1].SetTile(new Vector3Int(2, 0, 0), tile);
  183. m_PreviewTilemaps[1].SetTile(new Vector3Int(2, 1, 0), tile);
  184. for (int x = -1; x <= 1; x++)
  185. m_PreviewTilemaps[2].SetTile(new Vector3Int(x, -2, 0), tile);
  186. m_PreviewTilemaps[3].SetTile(new Vector3Int(1, 1, 0), tile);
  187. foreach (var tilemapRenderer in m_PreviewTilemapRenderers)
  188. tilemapRenderer.sortOrder = TilemapRenderer.SortOrder.TopRight;
  189. m_PreviewTilemapRenderers[0].sortingOrder = 0;
  190. m_PreviewTilemapRenderers[1].sortingOrder = -1;
  191. m_PreviewTilemapRenderers[2].sortingOrder = 1;
  192. m_PreviewTilemapRenderers[3].sortingOrder = 0;
  193. }
  194. }
  195. }