Advertisement
Guest User

Untitled

a guest
Dec 14th, 2018
62
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 8.45 KB | None | 0 0
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Text;
  5. using System.Threading.Tasks;
  6. using UnityEngine;
  7. using UnityEngine.UI;
  8.  
  9. namespace Assets.Code.Gui {
  10. public class GridLayoutCentered : LayoutGroup {
  11. public enum Corner {
  12. UpperLeft = 0, UpperRight = 1, LowerLeft = 2, LowerRight = 3
  13. }
  14. public enum Axis {
  15. Horizontal = 0, Vertical = 1
  16. }
  17. public enum Constraint {
  18. Flexible = 0, FixedColumnCount = 1, FixedRowCount = 2
  19. }
  20.  
  21. [SerializeField] protected Corner m_StartCorner = Corner.UpperLeft;
  22. public Corner startCorner {
  23. get {
  24. return m_StartCorner;
  25. }
  26. set {
  27. SetProperty( ref m_StartCorner, value );
  28. }
  29. }
  30.  
  31. [SerializeField] protected Axis m_StartAxis = Axis.Horizontal;
  32. public Axis startAxis {
  33. get {
  34. return m_StartAxis;
  35. }
  36. set {
  37. SetProperty( ref m_StartAxis, value );
  38. }
  39. }
  40.  
  41. [SerializeField] protected Vector2 m_CellSize = new Vector2( 100, 100 );
  42. public Vector2 cellSize {
  43. get {
  44. return m_CellSize;
  45. }
  46. set {
  47. SetProperty( ref m_CellSize, value );
  48. }
  49. }
  50.  
  51. [SerializeField] protected Vector2 m_Spacing = Vector2.zero;
  52. public Vector2 spacing {
  53. get {
  54. return m_Spacing;
  55. }
  56. set {
  57. SetProperty( ref m_Spacing, value );
  58. }
  59. }
  60.  
  61. [SerializeField] protected Constraint m_Constraint = Constraint.Flexible;
  62. public Constraint constraint {
  63. get {
  64. return m_Constraint;
  65. }
  66. set {
  67. SetProperty( ref m_Constraint, value );
  68. }
  69. }
  70.  
  71. [SerializeField] protected int m_ConstraintCount = 2;
  72. public int constraintCount {
  73. get {
  74. return m_ConstraintCount;
  75. }
  76. set {
  77. SetProperty( ref m_ConstraintCount, Mathf.Max( 1, value ) );
  78. }
  79. }
  80.  
  81. protected GridLayoutCentered() {
  82. }
  83.  
  84. #if UNITY_EDITOR
  85. protected override void OnValidate() {
  86. base.OnValidate();
  87. constraintCount = constraintCount;
  88. }
  89.  
  90. #endif
  91.  
  92. public override void CalculateLayoutInputHorizontal() {
  93. base.CalculateLayoutInputHorizontal();
  94.  
  95. int minColumns = 0;
  96. int preferredColumns = 0;
  97. if( m_Constraint == Constraint.FixedColumnCount ) {
  98. minColumns = preferredColumns = m_ConstraintCount;
  99. } else if( m_Constraint == Constraint.FixedRowCount ) {
  100. minColumns = preferredColumns = Mathf.CeilToInt( rectChildren.Count / ( float )m_ConstraintCount - 0.001f );
  101. } else {
  102. minColumns = 1;
  103. preferredColumns = Mathf.CeilToInt( Mathf.Sqrt( rectChildren.Count ) );
  104. }
  105.  
  106. SetLayoutInputForAxis(
  107. padding.horizontal + ( cellSize.x + spacing.x ) * minColumns - spacing.x,
  108. padding.horizontal + ( cellSize.x + spacing.x ) * preferredColumns - spacing.x,
  109. -1, 0 );
  110. }
  111.  
  112. public override void CalculateLayoutInputVertical() {
  113. int minRows = 0;
  114. if( m_Constraint == Constraint.FixedColumnCount ) {
  115. minRows = Mathf.CeilToInt( rectChildren.Count / ( float )m_ConstraintCount - 0.001f );
  116. } else if( m_Constraint == Constraint.FixedRowCount ) {
  117. minRows = m_ConstraintCount;
  118. } else {
  119. float width = rectTransform.rect.size.x;
  120. int cellCountX = Mathf.Max( 1, Mathf.FloorToInt( ( width - padding.horizontal + spacing.x + 0.001f ) / ( cellSize.x + spacing.x ) ) );
  121. minRows = Mathf.CeilToInt( rectChildren.Count / ( float )cellCountX );
  122. }
  123.  
  124. float minSpace = padding.vertical + ( cellSize.y + spacing.y ) * minRows - spacing.y;
  125. SetLayoutInputForAxis( minSpace, minSpace, -1, 1 );
  126. }
  127.  
  128. public override void SetLayoutHorizontal() {
  129. SetCellsAlongAxis( 0 );
  130. }
  131.  
  132. public override void SetLayoutVertical() {
  133. SetCellsAlongAxis( 1 );
  134. }
  135.  
  136. private void SetCellsAlongAxis( int axis ) {
  137. // Normally a Layout Controller should only set horizontal values when invoked for the horizontal axis
  138. // and only vertical values when invoked for the vertical axis.
  139. // However, in this case we set both the horizontal and vertical position when invoked for the vertical axis.
  140. // Since we only set the horizontal position and not the size, it shouldn't affect children's layout,
  141. // and thus shouldn't break the rule that all horizontal layout must be calculated before all vertical layout.
  142.  
  143. if( axis == 0 ) {
  144. // Only set the sizes when invoked for horizontal axis, not the positions.
  145. for( int i = 0; i < rectChildren.Count; i++ ) {
  146. RectTransform rect = rectChildren[ i ];
  147.  
  148. m_Tracker.Add( this, rect,
  149. DrivenTransformProperties.Anchors |
  150. DrivenTransformProperties.AnchoredPosition |
  151. DrivenTransformProperties.SizeDelta );
  152.  
  153. rect.anchorMin = Vector2.up;
  154. rect.anchorMax = Vector2.up;
  155. rect.sizeDelta = cellSize;
  156. }
  157. return;
  158. }
  159.  
  160. float width = rectTransform.rect.size.x;
  161. float height = rectTransform.rect.size.y;
  162.  
  163. int cellCountX = 1;
  164. int cellCountY = 1;
  165. if( m_Constraint == Constraint.FixedColumnCount ) {
  166. cellCountX = m_ConstraintCount;
  167. cellCountY = Mathf.CeilToInt( rectChildren.Count / ( float )cellCountX - 0.001f );
  168. } else if( m_Constraint == Constraint.FixedRowCount ) {
  169. cellCountY = m_ConstraintCount;
  170. cellCountX = Mathf.CeilToInt( rectChildren.Count / ( float )cellCountY - 0.001f );
  171. } else {
  172. if( cellSize.x + spacing.x <= 0 )
  173. cellCountX = int.MaxValue;
  174. else
  175. cellCountX = Mathf.Max( 1, Mathf.FloorToInt( ( width - padding.horizontal + spacing.x + 0.001f ) / ( cellSize.x + spacing.x ) ) );
  176.  
  177. if( cellSize.y + spacing.y <= 0 )
  178. cellCountY = int.MaxValue;
  179. else
  180. cellCountY = Mathf.Max( 1, Mathf.FloorToInt( ( height - padding.vertical + spacing.y + 0.001f ) / ( cellSize.y + spacing.y ) ) );
  181. }
  182.  
  183. int cornerX = ( int )startCorner % 2;
  184. int cornerY = ( int )startCorner / 2;
  185.  
  186. int cellsPerMainAxis, actualCellCountX, actualCellCountY;
  187. float lastRowActualSize;
  188. if( startAxis == Axis.Horizontal ) {
  189. cellsPerMainAxis = cellCountX;
  190. actualCellCountX = Mathf.Clamp( cellCountX, 1, rectChildren.Count );
  191. actualCellCountY = Mathf.Clamp( cellCountY, 1, Mathf.CeilToInt( rectChildren.Count / ( float )cellsPerMainAxis ) );
  192. int lastRowCount = actualCellCountX != 0 ? rectChildren.Count % actualCellCountX : 0;
  193. lastRowCount = lastRowCount == 0 ? actualCellCountX : lastRowCount;
  194. lastRowActualSize = lastRowCount * cellSize.x + ( lastRowCount - 1 ) * spacing.x;
  195. } else {
  196. cellsPerMainAxis = cellCountY;
  197. actualCellCountY = Mathf.Clamp( cellCountY, 1, rectChildren.Count );
  198. actualCellCountX = Mathf.Clamp( cellCountX, 1, Mathf.CeilToInt( rectChildren.Count / ( float )cellsPerMainAxis ) );
  199. int lastRowCount = actualCellCountY != 0 ? rectChildren.Count % actualCellCountY : 0;
  200. lastRowCount = lastRowCount == 0 ? actualCellCountY : lastRowCount;
  201. lastRowActualSize = lastRowCount * cellSize.y + ( lastRowCount - 1 ) * spacing.y;
  202. }
  203.  
  204. Vector2 requiredSpace = new Vector2(
  205. actualCellCountX * cellSize.x + ( actualCellCountX - 1 ) * spacing.x,
  206. actualCellCountY * cellSize.y + ( actualCellCountY - 1 ) * spacing.y
  207. );
  208. Vector2 startOffset = new Vector2(
  209. GetStartOffset( 0, requiredSpace.x ),
  210. GetStartOffset( 1, requiredSpace.y )
  211. );
  212.  
  213. float lastRowOffset;
  214.  
  215. if( startAxis == Axis.Horizontal ) {
  216. lastRowOffset = ( requiredSpace.x - lastRowActualSize ) / 2.0f;
  217. } else {
  218. lastRowOffset = ( requiredSpace.y - lastRowActualSize ) / 2.0f;
  219. }
  220.  
  221. for( int i = 0; i < rectChildren.Count; i++ ) {
  222. int positionX;
  223. int positionY;
  224. if( startAxis == Axis.Horizontal ) {
  225. positionX = i % cellsPerMainAxis;
  226. positionY = i / cellsPerMainAxis;
  227. } else {
  228. positionX = i / cellsPerMainAxis;
  229. positionY = i % cellsPerMainAxis;
  230. }
  231.  
  232. if( cornerX == 1 )
  233. positionX = actualCellCountX - 1 - positionX;
  234. if( cornerY == 1 )
  235. positionY = actualCellCountY - 1 - positionY;
  236.  
  237. if( startAxis == Axis.Vertical && positionX == cellCountX - 1 ) {
  238. SetChildAlongAxis( rectChildren[ i ], 1, startOffset.y + lastRowOffset + ( cellSize[ 1 ] + spacing[ 1 ] ) * positionY, cellSize[ 1 ] );
  239. } else {
  240. SetChildAlongAxis( rectChildren[ i ], 1, startOffset.y + ( cellSize[ 1 ] + spacing[ 1 ] ) * positionY, cellSize[ 1 ] );
  241. }
  242.  
  243. if( startAxis == Axis.Horizontal && positionY == cellCountY - 1 ) {
  244. SetChildAlongAxis( rectChildren[ i ], 0, startOffset.x + lastRowOffset + ( cellSize[ 0 ] + spacing[ 0 ] ) * positionX, cellSize[ 0 ] );
  245. } else {
  246. SetChildAlongAxis( rectChildren[ i ], 0, startOffset.x + ( cellSize[ 0 ] + spacing[ 0 ] ) * positionX, cellSize[ 0 ] );
  247. }
  248. }
  249. }
  250. }
  251. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement