SCGridLayoutGroup.cs 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476
  1. 
  2. using UnityEngine;
  3. using UnityEditor;
  4. //using System.Windows.Markup;
  5. //using UnityScript.Steps;
  6. using Unity.Collections;
  7. [ExecuteAlways]//脚本在任意情况下均会运行
  8. public class SCGridLayoutGroup : SCBaseLayoutGroup
  9. {
  10. /// <summary>
  11. /// 组的布局类型
  12. /// </summary>
  13. [SerializeField]
  14. private LayoutTypes layoutType = LayoutTypes.Horizontal;
  15. public LayoutTypes LayoutType
  16. {
  17. get { return layoutType; }
  18. set { layoutType = value; }
  19. }
  20. /// <summary>
  21. /// 不满一行时的子物体对齐方式
  22. /// </summary>
  23. [SerializeField]
  24. private GroupHorizontalAlignment groupHorizontalAlign = GroupHorizontalAlignment.Left;
  25. public GroupHorizontalAlignment GroupHorizontalAlign
  26. {
  27. get { return groupHorizontalAlign; }
  28. set { groupHorizontalAlign = value; }
  29. }
  30. /// <summary>
  31. /// 不满一列时的子物体对齐方式
  32. /// </summary>
  33. [SerializeField]
  34. private GroupVerticalAlignment groupVerticalAlign = GroupVerticalAlignment.Top;
  35. public GroupVerticalAlignment GroupVerticalAlign
  36. {
  37. get { return groupVerticalAlign; }
  38. set { groupVerticalAlign = value; }
  39. }
  40. /// <summary>
  41. /// 子物体的队形类型
  42. /// </summary>
  43. [SerializeField]
  44. private GroupArrayTypes groupArrayType =
  45. GroupArrayTypes.Plane;
  46. public GroupArrayTypes GroupArrayType {
  47. get { return groupArrayType; }
  48. set { groupArrayType = value; }
  49. }
  50. /// <summary>
  51. /// 组锚点相对于基类的位置
  52. /// </summary>
  53. [SerializeField]
  54. private AnchorRelativeBase anchorLayout = AnchorRelativeBase.MiddleCenter;
  55. public AnchorRelativeBase AnchorLayout
  56. {
  57. get { return anchorLayout; }
  58. set { anchorLayout = value; }
  59. }
  60. /// <summary>
  61. /// 各子物体的面向
  62. /// </summary>
  63. [SerializeField]
  64. private ObjFacingTypes facingType = ObjFacingTypes.None;
  65. public ObjFacingTypes FacingType
  66. {
  67. get { return facingType; }
  68. set { facingType = value; }
  69. }
  70. /// <summary>
  71. /// 列数
  72. /// </summary>
  73. [SerializeField]
  74. private int columns = 2;
  75. public int Columns {
  76. get { return columns; }
  77. set {
  78. if (LayoutType == LayoutTypes.Horizontal)
  79. {
  80. return;
  81. }
  82. columns = value; }
  83. }
  84. /// <summary>
  85. /// 行数
  86. /// </summary>
  87. [SerializeField]
  88. private int rows = 2;
  89. public int Rows
  90. {
  91. get { return rows; }
  92. set
  93. {
  94. if (LayoutType == LayoutTypes.Vertical)
  95. {
  96. return;
  97. }
  98. rows = value;
  99. }
  100. }
  101. /// <summary>
  102. /// 横向间距
  103. /// </summary>
  104. [SerializeField]
  105. private float spaceX = 2f;
  106. public float SpaceX {
  107. get { return spaceX; }
  108. set { spaceX = value; }
  109. }
  110. /// <summary>
  111. /// 纵向间距
  112. /// </summary>
  113. [SerializeField]
  114. private float spaceY = 2f;
  115. public float SpaceY
  116. {
  117. get { return spaceY; }
  118. set { spaceY = value; }
  119. }
  120. [SerializeField]
  121. [Range(-100f, 100f)]
  122. private float childOffsetX = 0f;
  123. public float ChildOffsetX
  124. {
  125. get { return childOffsetX; }
  126. set { childOffsetX = value; }
  127. }
  128. [SerializeField]
  129. [Range(-100f, 100f)]
  130. private float childOffsetY= 0f;
  131. public float ChildOffsetY
  132. {
  133. get { return childOffsetY; }
  134. set { childOffsetY = value; }
  135. }
  136. /// <summary>
  137. /// 子物体Z轴相较于基类的位置
  138. /// </summary>
  139. [SerializeField]
  140. [Range(-100f, 100f)]
  141. private float childOffsetZ = 0f;
  142. public float ChildOffsetZ
  143. {
  144. get { return childOffsetZ; }
  145. set { childOffsetZ = value; }
  146. }
  147. /// <summary>
  148. /// 半径
  149. /// </summary>
  150. [SerializeField]
  151. [Range(0.05f,200)]
  152. private float radius = 2f;
  153. public float Radius
  154. {
  155. get { return radius; }
  156. set { radius = value; }
  157. }
  158. /// <summary>
  159. /// 辐射角度
  160. /// </summary>
  161. [SerializeField]
  162. [Range(5f, 360f)]
  163. private float radialRange = 180f;
  164. public float RadialRange {
  165. get { return radialRange; }
  166. set { radialRange = value; }
  167. }
  168. /// <summary>
  169. /// 锚点是否用轴对齐
  170. /// </summary>
  171. [SerializeField]
  172. private bool isAnchorWithAxis = false;
  173. public bool IsAnchorWithAxis
  174. {
  175. get { return isAnchorWithAxis; }
  176. set { isAnchorWithAxis = value; }
  177. }
  178. private GroupObj tempobj;
  179. private Vector3[] childPos;
  180. private Vector3 newPos;
  181. private int objCount;
  182. private int rowMax;
  183. private int colMax;
  184. private float acnhoroffsetX;
  185. private float anchoroffsetY;
  186. private float shortOffsetX;
  187. private float shortOffsetY;
  188. private void Init()//初始化值
  189. {
  190. childPos = new Vector3[ObjList.Count];
  191. newPos = Vector3.zero;
  192. objCount = 0;
  193. rowMax = 0;
  194. colMax = 0;
  195. acnhoroffsetX = 0;
  196. anchoroffsetY = 0;
  197. shortOffsetX = 0;
  198. shortOffsetY = 0;
  199. }
  200. protected override void LayoutChildren()
  201. {
  202. Init();
  203. SetObjPos();
  204. ArrayType();
  205. }
  206. private void Update()
  207. {
  208. }
  209. private void SetObjPos()//子物体的位置
  210. {
  211. switch (LayoutType)
  212. {
  213. case LayoutTypes.Horizontal:
  214. colMax = Columns;
  215. rowMax= Mathf.CeilToInt((float)ObjList.Count / Columns);
  216. break;
  217. case LayoutTypes.Vertical:
  218. rowMax = Rows;
  219. colMax = Mathf.CeilToInt((float)ObjList.Count / Rows);
  220. break;
  221. }
  222. acnhoroffsetX = (colMax * 0.5f * SpaceX);
  223. if (AnchorLayout == AnchorRelativeBase.LowerLeft || AnchorLayout == AnchorRelativeBase.UpperLeft || AnchorLayout == AnchorRelativeBase.MiddleLeft)
  224. {
  225. acnhoroffsetX = IsAnchorWithAxis ? 0.5f * SpaceX : 0;
  226. }
  227. else if (AnchorLayout == AnchorRelativeBase.LowerRight || AnchorLayout == AnchorRelativeBase.UpperRight || AnchorLayout == AnchorRelativeBase.MiddleRight)
  228. {
  229. acnhoroffsetX = IsAnchorWithAxis ? (colMax - 0.5f) * SpaceX : colMax * SpaceX;
  230. }
  231. anchoroffsetY = (rowMax * 0.5f * SpaceY);
  232. if (AnchorLayout == AnchorRelativeBase.UpperLeft || AnchorLayout == AnchorRelativeBase.UpperCenter || AnchorLayout == AnchorRelativeBase.UpperRight)
  233. {
  234. anchoroffsetY = IsAnchorWithAxis ? 0.5f * SpaceY : 0;
  235. }
  236. else if (AnchorLayout == AnchorRelativeBase.LowerLeft || AnchorLayout == AnchorRelativeBase.LowerCenter || AnchorLayout == AnchorRelativeBase.LowerRight)
  237. {
  238. anchoroffsetY = IsAnchorWithAxis ? (rowMax - 0.5f) * SpaceY : rowMax * SpaceY;
  239. }
  240. if (LayoutType == LayoutTypes.Horizontal)
  241. {
  242. for (int i = 0; i < rowMax; i++)
  243. {
  244. for (int j = 0; j < colMax; j++)
  245. {
  246. if (i==rowMax-1)
  247. {
  248. if (GroupHorizontalAlign == GroupHorizontalAlignment.Left)
  249. {
  250. shortOffsetX = 0;
  251. }
  252. else if (GroupHorizontalAlign == GroupHorizontalAlignment.Center)
  253. {
  254. shortOffsetX = SpaceX * ((colMax - (ObjList.Count % colMax)) % colMax) * 0.5f;
  255. }
  256. else if (GroupHorizontalAlign == GroupHorizontalAlignment.Right)
  257. {
  258. shortOffsetX = SpaceX * ((colMax - (ObjList.Count % colMax)) % colMax);
  259. }
  260. }
  261. if (objCount< ObjList.Count)
  262. {
  263. childPos[objCount].Set(0.5f * SpaceX * (1 + 2 * j) - acnhoroffsetX + shortOffsetX+ ChildOffsetX, (0.5f * SpaceY * (-1 - 2 * i)) + anchoroffsetY + shortOffsetY+ChildOffsetY, 0.0f);
  264. }
  265. objCount++;
  266. }
  267. }
  268. }
  269. else
  270. {
  271. for (int i = 0; i < colMax; i++)
  272. {
  273. for (int j = 0; j < rowMax; j++)
  274. {
  275. if (i==colMax-1)
  276. {
  277. if (GroupVerticalAlign == GroupVerticalAlignment.Top)
  278. {
  279. shortOffsetY = 0;
  280. }
  281. else if (GroupVerticalAlign == GroupVerticalAlignment.Middle)
  282. {
  283. shortOffsetY = -SpaceY * ((rowMax - (ObjList.Count % rowMax)) % rowMax) * 0.5f;
  284. }
  285. else if (GroupVerticalAlign == GroupVerticalAlignment.Bottom)
  286. {
  287. shortOffsetY = -SpaceY * ((rowMax - (ObjList.Count % rowMax)) % rowMax);
  288. }
  289. }
  290. if (objCount< ObjList.Count)
  291. {
  292. childPos[objCount].Set(0.5f * SpaceX * (1 + 2 * i )- acnhoroffsetX + shortOffsetX+ ChildOffsetX, (0.5f * SpaceY * ( - 1 - 2 * j))+ anchoroffsetY + shortOffsetY+childOffsetY, 0.0f);
  293. }
  294. objCount++;
  295. }
  296. }
  297. }
  298. }
  299. private void ArrayType()//赋予子物体位置
  300. {
  301. switch (GroupArrayType) {
  302. case GroupArrayTypes.Plane:
  303. for (int i = 0; i < ObjList.Count; i++)
  304. {
  305. tempobj = ObjList[i];
  306. newPos = childPos[i];
  307. newPos.z = ChildOffsetZ;
  308. tempobj.Transform.localPosition = newPos;
  309. ObjFacing(tempobj);
  310. ObjList[i] = tempobj;
  311. }
  312. break;
  313. case GroupArrayTypes.Cylinder:
  314. for (int i = 0; i < ObjList.Count; i++)
  315. {
  316. tempobj = ObjList[i];
  317. newPos = CylinderArray(childPos[i], radius);
  318. tempobj.Transform.localPosition = newPos;
  319. ObjFacing(tempobj);
  320. ObjList[i] = tempobj;
  321. }
  322. break;
  323. case GroupArrayTypes.Radial:
  324. int tempColumn=0;
  325. int tempRow=1;
  326. for (int i = 0; i < ObjList.Count ; i++)
  327. {
  328. tempobj = ObjList[i];
  329. newPos = RadialArray(childPos[i], radius, radialRange, tempRow, rowMax, tempColumn, colMax);
  330. if (tempColumn==columns-1)
  331. {
  332. tempColumn = 0;
  333. tempRow++;
  334. }
  335. else
  336. {
  337. tempColumn++;
  338. }
  339. tempobj.Transform.localPosition = newPos;
  340. ObjFacing(tempobj);
  341. ObjList[i] = tempobj;
  342. }
  343. break;
  344. case GroupArrayTypes.Sphere:
  345. for (int i = 0; i < ObjList.Count ; i++)
  346. {
  347. tempobj = ObjList[i];
  348. newPos = SphereArray(childPos[i], radius);
  349. tempobj.Transform.localPosition = newPos;
  350. ObjFacing(tempobj);
  351. ObjList[i] = tempobj;
  352. }
  353. break;
  354. case GroupArrayTypes.Round:
  355. for (int i = 0; i < ObjList.Count; i++)
  356. {
  357. tempobj = ObjList[i];
  358. newPos = RoundArray( childPos[i],radius, i+1,ObjList.Count);
  359. newPos.Set(newPos.x+ChildOffsetX, newPos.y + ChildOffsetY, newPos.z +ChildOffsetZ);
  360. tempobj.Transform.localPosition = newPos;
  361. ObjFacing(tempobj);
  362. ObjList[i] = tempobj;
  363. }
  364. break;
  365. }
  366. }
  367. private Vector3 CylinderArray(Vector3 objPos,float radius)
  368. {
  369. float circ = 2.0f * Mathf.PI * radius;
  370. float xAngle = (objPos.x / circ) * 360f;
  371. objPos.Set(0.0f, objPos.y, radius);
  372. Quaternion rot = Quaternion.Euler(0.0f, xAngle, 0.0f);
  373. objPos = rot * objPos;
  374. return objPos;
  375. }
  376. private Vector3 SphereArray(Vector3 objPos, float radius)
  377. {
  378. float circ = 2.0f * Mathf.PI * radius;
  379. float XAngle = (objPos.x / circ) * 360f;
  380. float YAngle = -(objPos.y / circ) * 360f;
  381. objPos.Set(0.0f, 0.0f, radius);
  382. Quaternion rot = Quaternion.Euler(YAngle, XAngle, 0.0f);
  383. objPos = rot * objPos;
  384. return objPos;
  385. }
  386. private Vector3 RadialArray(Vector3 objPos, float radius ,float radialRange,int row,int rowMax,int column,int colMax)
  387. {
  388. float radialSpaceAngle = radialRange / colMax;
  389. objPos.Set(0.0f, 0.0f, (radius / rowMax) * row);
  390. float YAngle= radialSpaceAngle * (column - (colMax * 0.5f)) + (radialSpaceAngle * .5f);
  391. Quaternion rot = Quaternion.Euler(0.0f, YAngle, 0.0f);
  392. objPos = rot * objPos;
  393. return objPos;
  394. }
  395. private Vector3 RoundArray(Vector3 objPos , float radius,int i,int totalCount)
  396. {
  397. float angle = (360f *i )/ totalCount;
  398. float x = radius * Mathf.Cos(angle* Mathf.PI / 180f);
  399. float y = radius * Mathf.Sin(angle* Mathf.PI / 180f);
  400. objPos.Set(x,0,y);
  401. return objPos;
  402. }
  403. private void ObjFacing(GroupObj obj)//子物体的面向
  404. {
  405. Vector3 centerPos;
  406. Vector3 FacingNode;
  407. switch (FacingType)
  408. {
  409. case ObjFacingTypes.None:
  410. obj.Transform.transform.localEulerAngles = Vector3.zero;
  411. break;
  412. case ObjFacingTypes.FaceOrigin:
  413. obj.Transform.rotation = Quaternion.LookRotation(obj.Transform.position-transform.position,transform.up);
  414. break;
  415. case ObjFacingTypes.FaceOriginReversed:
  416. obj.Transform.rotation = Quaternion.LookRotation(transform.position- obj.Transform.position,transform.up);
  417. break;
  418. case ObjFacingTypes.FaceCenterAxis:
  419. centerPos = Vector3.Project(obj.Transform.position-transform.position,transform.up);//返回一个向量在指定轴上的投影
  420. FacingNode = transform.position + centerPos;
  421. obj.Transform.rotation = Quaternion.LookRotation(obj.Transform.position - FacingNode, transform.up);
  422. break;
  423. case ObjFacingTypes.FaceCenterAxisReversed:
  424. centerPos = Vector3.Project(obj.Transform.position - transform.position, transform.up);//返回一个向量在指定轴上的投影
  425. FacingNode = transform.position + centerPos;
  426. obj.Transform.rotation = Quaternion.LookRotation(FacingNode- obj.Transform.position , transform.up);
  427. break;
  428. case ObjFacingTypes.FaceParentDown:
  429. obj.Transform.forward = transform.rotation * Vector3.down;
  430. break;
  431. case ObjFacingTypes.FaceParentUp:
  432. obj.Transform.forward = transform.rotation * Vector3.up;
  433. break;
  434. case ObjFacingTypes.FaceParentFoward:
  435. obj.Transform.forward = transform.rotation * Vector3.forward;
  436. break;
  437. case ObjFacingTypes.FaceParentBack:
  438. obj.Transform.forward = transform.rotation * Vector3.back;
  439. break;
  440. }
  441. }
  442. private void setNull()
  443. {
  444. tempobj = null;
  445. childPos = null;
  446. }
  447. private void OnDestroy()
  448. {
  449. setNull();
  450. }
  451. }