설명 없음
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.

HexagonalRuleTile.cs 7.7KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196
  1. using System;
  2. namespace UnityEngine
  3. {
  4. /// <summary>
  5. /// Generic visual tile for creating different tilesets like terrain, pipeline, random or animated tiles.
  6. /// This is templated to accept a Neighbor Rule Class for Custom Rules.
  7. /// Use this for Hexagonal Grids.
  8. /// </summary>
  9. /// <typeparam name="T">Neighbor Rule Class for Custom Rules</typeparam>
  10. public class HexagonalRuleTile<T> : HexagonalRuleTile
  11. {
  12. /// <summary>
  13. /// Returns the Neighbor Rule Class type for this Rule Tile.
  14. /// </summary>
  15. public sealed override Type m_NeighborType => typeof(T);
  16. }
  17. /// <summary>
  18. /// Generic visual tile for creating different tilesets like terrain, pipeline, random or animated tiles.
  19. /// Use this for Hexagonal Grids.
  20. /// </summary>
  21. [Serializable]
  22. [HelpURL("https://docs.unity3d.com/Packages/com.unity.2d.tilemap.extras@latest/index.html?subfolder=/manual/RuleTile.html")]
  23. public class HexagonalRuleTile : RuleTile
  24. {
  25. /// <summary>
  26. /// Angle in which the HexagonalRuleTile is rotated by for matching in Degrees.
  27. /// </summary>
  28. public override int m_RotationAngle => 60;
  29. private static float[] m_CosAngleArr1 = {
  30. Mathf.Cos(0 * Mathf.Deg2Rad),
  31. Mathf.Cos(-60 * Mathf.Deg2Rad),
  32. Mathf.Cos(-120 * Mathf.Deg2Rad),
  33. Mathf.Cos(-180 * Mathf.Deg2Rad),
  34. Mathf.Cos(-240 * Mathf.Deg2Rad),
  35. Mathf.Cos(-300 * Mathf.Deg2Rad),
  36. };
  37. private static float[] m_SinAngleArr1 = {
  38. Mathf.Sin(0 * Mathf.Deg2Rad),
  39. Mathf.Sin(-60 * Mathf.Deg2Rad),
  40. Mathf.Sin(-120 * Mathf.Deg2Rad),
  41. Mathf.Sin(-180 * Mathf.Deg2Rad),
  42. Mathf.Sin(-240 * Mathf.Deg2Rad),
  43. Mathf.Sin(-300 * Mathf.Deg2Rad),
  44. };
  45. private static float[] m_CosAngleArr2 = {
  46. Mathf.Cos(0 * Mathf.Deg2Rad),
  47. Mathf.Cos(60 * Mathf.Deg2Rad),
  48. Mathf.Cos(120 * Mathf.Deg2Rad),
  49. Mathf.Cos(180 * Mathf.Deg2Rad),
  50. Mathf.Cos(240 * Mathf.Deg2Rad),
  51. Mathf.Cos(300 * Mathf.Deg2Rad),
  52. };
  53. private static float[] m_SinAngleArr2 = {
  54. Mathf.Sin(0 * Mathf.Deg2Rad),
  55. Mathf.Sin(60 * Mathf.Deg2Rad),
  56. Mathf.Sin(120 * Mathf.Deg2Rad),
  57. Mathf.Sin(180 * Mathf.Deg2Rad),
  58. Mathf.Sin(240 * Mathf.Deg2Rad),
  59. Mathf.Sin(300 * Mathf.Deg2Rad),
  60. };
  61. /// <summary>
  62. /// Whether this is a flat top Hexagonal Tile
  63. /// </summary>
  64. [DontOverride] public bool m_FlatTop;
  65. static float m_TilemapToWorldYScale = Mathf.Pow(1 - Mathf.Pow(0.5f, 2f), 0.5f);
  66. /// <summary>
  67. /// Converts a Tilemap Position to World Position.
  68. /// </summary>
  69. /// <param name="tilemapPosition">Tilemap Position to convert.</param>
  70. /// <returns>World Position.</returns>
  71. public static Vector3 TilemapPositionToWorldPosition(Vector3Int tilemapPosition)
  72. {
  73. Vector3 worldPosition = new Vector3(tilemapPosition.x, tilemapPosition.y);
  74. if (tilemapPosition.y % 2 != 0)
  75. worldPosition.x += 0.5f;
  76. worldPosition.y *= m_TilemapToWorldYScale;
  77. return worldPosition;
  78. }
  79. /// <summary>
  80. /// Converts a World Position to Tilemap Position.
  81. /// </summary>
  82. /// <param name="worldPosition">World Position to convert.</param>
  83. /// <returns>Tilemap Position.</returns>
  84. public static Vector3Int WorldPositionToTilemapPosition(Vector3 worldPosition)
  85. {
  86. worldPosition.y /= m_TilemapToWorldYScale;
  87. Vector3Int tilemapPosition = new Vector3Int();
  88. tilemapPosition.y = Mathf.RoundToInt(worldPosition.y);
  89. if (tilemapPosition.y % 2 != 0)
  90. tilemapPosition.x = Mathf.RoundToInt(worldPosition.x - 0.5f);
  91. else
  92. tilemapPosition.x = Mathf.RoundToInt(worldPosition.x);
  93. return tilemapPosition;
  94. }
  95. /// <summary>
  96. /// Get the offset for the given position with the given offset.
  97. /// </summary>
  98. /// <param name="position">Position to offset.</param>
  99. /// <param name="offset">Offset for the position.</param>
  100. /// <returns>The offset position.</returns>
  101. public override Vector3Int GetOffsetPosition(Vector3Int position, Vector3Int offset)
  102. {
  103. Vector3Int offsetPosition = position + offset;
  104. if (offset.y % 2 != 0 && position.y % 2 != 0)
  105. offsetPosition.x += 1;
  106. return offsetPosition;
  107. }
  108. /// <summary>
  109. /// Get the reversed offset for the given position with the given offset.
  110. /// </summary>
  111. /// <param name="position">Position to offset.</param>
  112. /// <param name="offset">Offset for the position.</param>
  113. /// <returns>The reversed offset position.</returns>
  114. public override Vector3Int GetOffsetPositionReverse(Vector3Int position, Vector3Int offset)
  115. {
  116. return GetOffsetPosition(position, GetRotatedPosition(offset, 180));
  117. }
  118. /// <summary>
  119. /// Gets a rotated position given its original position and the rotation in degrees.
  120. /// </summary>
  121. /// <param name="position">Original position of Tile.</param>
  122. /// <param name="rotation">Rotation in degrees.</param>
  123. /// <returns>Rotated position of Tile.</returns>
  124. public override Vector3Int GetRotatedPosition(Vector3Int position, int rotation)
  125. {
  126. if (rotation != 0)
  127. {
  128. Vector3 worldPosition = TilemapPositionToWorldPosition(position);
  129. int index = rotation / 60;
  130. if (m_FlatTop)
  131. {
  132. worldPosition = new Vector3(
  133. worldPosition.x * m_CosAngleArr2[index] - worldPosition.y * m_SinAngleArr2[index],
  134. worldPosition.x * m_SinAngleArr2[index] + worldPosition.y * m_CosAngleArr2[index]
  135. );
  136. }
  137. else
  138. {
  139. worldPosition = new Vector3(
  140. worldPosition.x * m_CosAngleArr1[index] - worldPosition.y * m_SinAngleArr1[index],
  141. worldPosition.x * m_SinAngleArr1[index] + worldPosition.y * m_CosAngleArr1[index]
  142. );
  143. }
  144. position = WorldPositionToTilemapPosition(worldPosition);
  145. }
  146. return position;
  147. }
  148. /// <summary>
  149. /// Gets a mirrored position given its original position and the mirroring axii.
  150. /// </summary>
  151. /// <param name="position">Original position of Tile.</param>
  152. /// <param name="mirrorX">Mirror in the X Axis.</param>
  153. /// <param name="mirrorY">Mirror in the Y Axis.</param>
  154. /// <returns>Mirrored position of Tile.</returns>
  155. public override Vector3Int GetMirroredPosition(Vector3Int position, bool mirrorX, bool mirrorY)
  156. {
  157. if (mirrorX || mirrorY)
  158. {
  159. Vector3 worldPosition = TilemapPositionToWorldPosition(position);
  160. if (m_FlatTop)
  161. {
  162. if (mirrorX)
  163. worldPosition.y *= -1;
  164. if (mirrorY)
  165. worldPosition.x *= -1;
  166. }
  167. else
  168. {
  169. if (mirrorX)
  170. worldPosition.x *= -1;
  171. if (mirrorY)
  172. worldPosition.y *= -1;
  173. }
  174. position = WorldPositionToTilemapPosition(worldPosition);
  175. }
  176. return position;
  177. }
  178. }
  179. }