123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476 |
-
- using UnityEngine;
- using UnityEditor;
- //using System.Windows.Markup;
- //using UnityScript.Steps;
- using Unity.Collections;
- [ExecuteAlways]//脚本在任意情况下均会运行
- public class SCGridLayoutGroup : SCBaseLayoutGroup
- {
- /// <summary>
- /// 组的布局类型
- /// </summary>
- [SerializeField]
- private LayoutTypes layoutType = LayoutTypes.Horizontal;
- public LayoutTypes LayoutType
- {
- get { return layoutType; }
- set { layoutType = value; }
- }
- /// <summary>
- /// 不满一行时的子物体对齐方式
- /// </summary>
- [SerializeField]
- private GroupHorizontalAlignment groupHorizontalAlign = GroupHorizontalAlignment.Left;
- public GroupHorizontalAlignment GroupHorizontalAlign
- {
- get { return groupHorizontalAlign; }
- set { groupHorizontalAlign = value; }
- }
- /// <summary>
- /// 不满一列时的子物体对齐方式
- /// </summary>
- [SerializeField]
- private GroupVerticalAlignment groupVerticalAlign = GroupVerticalAlignment.Top;
- public GroupVerticalAlignment GroupVerticalAlign
- {
- get { return groupVerticalAlign; }
- set { groupVerticalAlign = value; }
- }
- /// <summary>
- /// 子物体的队形类型
- /// </summary>
- [SerializeField]
- private GroupArrayTypes groupArrayType =
- GroupArrayTypes.Plane;
- public GroupArrayTypes GroupArrayType {
- get { return groupArrayType; }
- set { groupArrayType = value; }
- }
- /// <summary>
- /// 组锚点相对于基类的位置
- /// </summary>
- [SerializeField]
- private AnchorRelativeBase anchorLayout = AnchorRelativeBase.MiddleCenter;
- public AnchorRelativeBase AnchorLayout
- {
- get { return anchorLayout; }
- set { anchorLayout = value; }
- }
- /// <summary>
- /// 各子物体的面向
- /// </summary>
- [SerializeField]
- private ObjFacingTypes facingType = ObjFacingTypes.None;
- public ObjFacingTypes FacingType
- {
- get { return facingType; }
- set { facingType = value; }
- }
- /// <summary>
- /// 列数
- /// </summary>
- [SerializeField]
- private int columns = 2;
- public int Columns {
- get { return columns; }
- set {
- if (LayoutType == LayoutTypes.Horizontal)
- {
- return;
- }
- columns = value; }
- }
- /// <summary>
- /// 行数
- /// </summary>
- [SerializeField]
- private int rows = 2;
- public int Rows
- {
- get { return rows; }
- set
- {
- if (LayoutType == LayoutTypes.Vertical)
- {
- return;
- }
- rows = value;
- }
- }
- /// <summary>
- /// 横向间距
- /// </summary>
- [SerializeField]
- private float spaceX = 2f;
- public float SpaceX {
- get { return spaceX; }
- set { spaceX = value; }
- }
- /// <summary>
- /// 纵向间距
- /// </summary>
- [SerializeField]
- private float spaceY = 2f;
- public float SpaceY
- {
- get { return spaceY; }
- set { spaceY = value; }
- }
- [SerializeField]
- [Range(-100f, 100f)]
- private float childOffsetX = 0f;
- public float ChildOffsetX
- {
- get { return childOffsetX; }
- set { childOffsetX = value; }
- }
- [SerializeField]
- [Range(-100f, 100f)]
- private float childOffsetY= 0f;
- public float ChildOffsetY
- {
- get { return childOffsetY; }
- set { childOffsetY = value; }
- }
- /// <summary>
- /// 子物体Z轴相较于基类的位置
- /// </summary>
- [SerializeField]
- [Range(-100f, 100f)]
- private float childOffsetZ = 0f;
- public float ChildOffsetZ
- {
- get { return childOffsetZ; }
- set { childOffsetZ = value; }
- }
- /// <summary>
- /// 半径
- /// </summary>
- [SerializeField]
- [Range(0.05f,200)]
- private float radius = 2f;
- public float Radius
- {
- get { return radius; }
- set { radius = value; }
- }
- /// <summary>
- /// 辐射角度
- /// </summary>
- [SerializeField]
- [Range(5f, 360f)]
- private float radialRange = 180f;
- public float RadialRange {
- get { return radialRange; }
- set { radialRange = value; }
- }
- /// <summary>
- /// 锚点是否用轴对齐
- /// </summary>
- [SerializeField]
- private bool isAnchorWithAxis = false;
- public bool IsAnchorWithAxis
- {
- get { return isAnchorWithAxis; }
- set { isAnchorWithAxis = value; }
- }
- private GroupObj tempobj;
- private Vector3[] childPos;
- private Vector3 newPos;
- private int objCount;
- private int rowMax;
- private int colMax;
- private float acnhoroffsetX;
- private float anchoroffsetY;
- private float shortOffsetX;
- private float shortOffsetY;
- private void Init()//初始化值
- {
- childPos = new Vector3[ObjList.Count];
- newPos = Vector3.zero;
- objCount = 0;
- rowMax = 0;
- colMax = 0;
- acnhoroffsetX = 0;
- anchoroffsetY = 0;
- shortOffsetX = 0;
- shortOffsetY = 0;
- }
- protected override void LayoutChildren()
- {
- Init();
- SetObjPos();
- ArrayType();
- }
- private void Update()
- {
- }
- private void SetObjPos()//子物体的位置
- {
- switch (LayoutType)
- {
- case LayoutTypes.Horizontal:
- colMax = Columns;
- rowMax= Mathf.CeilToInt((float)ObjList.Count / Columns);
- break;
- case LayoutTypes.Vertical:
- rowMax = Rows;
- colMax = Mathf.CeilToInt((float)ObjList.Count / Rows);
- break;
- }
- acnhoroffsetX = (colMax * 0.5f * SpaceX);
- if (AnchorLayout == AnchorRelativeBase.LowerLeft || AnchorLayout == AnchorRelativeBase.UpperLeft || AnchorLayout == AnchorRelativeBase.MiddleLeft)
- {
- acnhoroffsetX = IsAnchorWithAxis ? 0.5f * SpaceX : 0;
- }
- else if (AnchorLayout == AnchorRelativeBase.LowerRight || AnchorLayout == AnchorRelativeBase.UpperRight || AnchorLayout == AnchorRelativeBase.MiddleRight)
- {
- acnhoroffsetX = IsAnchorWithAxis ? (colMax - 0.5f) * SpaceX : colMax * SpaceX;
- }
- anchoroffsetY = (rowMax * 0.5f * SpaceY);
- if (AnchorLayout == AnchorRelativeBase.UpperLeft || AnchorLayout == AnchorRelativeBase.UpperCenter || AnchorLayout == AnchorRelativeBase.UpperRight)
- {
- anchoroffsetY = IsAnchorWithAxis ? 0.5f * SpaceY : 0;
- }
- else if (AnchorLayout == AnchorRelativeBase.LowerLeft || AnchorLayout == AnchorRelativeBase.LowerCenter || AnchorLayout == AnchorRelativeBase.LowerRight)
- {
- anchoroffsetY = IsAnchorWithAxis ? (rowMax - 0.5f) * SpaceY : rowMax * SpaceY;
- }
- if (LayoutType == LayoutTypes.Horizontal)
- {
- for (int i = 0; i < rowMax; i++)
- {
- for (int j = 0; j < colMax; j++)
- {
- if (i==rowMax-1)
- {
- if (GroupHorizontalAlign == GroupHorizontalAlignment.Left)
- {
- shortOffsetX = 0;
- }
- else if (GroupHorizontalAlign == GroupHorizontalAlignment.Center)
- {
- shortOffsetX = SpaceX * ((colMax - (ObjList.Count % colMax)) % colMax) * 0.5f;
- }
- else if (GroupHorizontalAlign == GroupHorizontalAlignment.Right)
- {
- shortOffsetX = SpaceX * ((colMax - (ObjList.Count % colMax)) % colMax);
- }
- }
- if (objCount< ObjList.Count)
- {
- childPos[objCount].Set(0.5f * SpaceX * (1 + 2 * j) - acnhoroffsetX + shortOffsetX+ ChildOffsetX, (0.5f * SpaceY * (-1 - 2 * i)) + anchoroffsetY + shortOffsetY+ChildOffsetY, 0.0f);
- }
- objCount++;
- }
- }
- }
- else
- {
- for (int i = 0; i < colMax; i++)
- {
- for (int j = 0; j < rowMax; j++)
- {
- if (i==colMax-1)
- {
- if (GroupVerticalAlign == GroupVerticalAlignment.Top)
- {
- shortOffsetY = 0;
- }
- else if (GroupVerticalAlign == GroupVerticalAlignment.Middle)
- {
- shortOffsetY = -SpaceY * ((rowMax - (ObjList.Count % rowMax)) % rowMax) * 0.5f;
- }
- else if (GroupVerticalAlign == GroupVerticalAlignment.Bottom)
- {
- shortOffsetY = -SpaceY * ((rowMax - (ObjList.Count % rowMax)) % rowMax);
- }
- }
- if (objCount< ObjList.Count)
- {
- childPos[objCount].Set(0.5f * SpaceX * (1 + 2 * i )- acnhoroffsetX + shortOffsetX+ ChildOffsetX, (0.5f * SpaceY * ( - 1 - 2 * j))+ anchoroffsetY + shortOffsetY+childOffsetY, 0.0f);
- }
- objCount++;
- }
- }
- }
- }
- private void ArrayType()//赋予子物体位置
- {
- switch (GroupArrayType) {
- case GroupArrayTypes.Plane:
- for (int i = 0; i < ObjList.Count; i++)
- {
- tempobj = ObjList[i];
- newPos = childPos[i];
- newPos.z = ChildOffsetZ;
- tempobj.Transform.localPosition = newPos;
- ObjFacing(tempobj);
- ObjList[i] = tempobj;
- }
- break;
- case GroupArrayTypes.Cylinder:
- for (int i = 0; i < ObjList.Count; i++)
- {
- tempobj = ObjList[i];
- newPos = CylinderArray(childPos[i], radius);
- tempobj.Transform.localPosition = newPos;
- ObjFacing(tempobj);
- ObjList[i] = tempobj;
- }
- break;
- case GroupArrayTypes.Radial:
- int tempColumn=0;
- int tempRow=1;
- for (int i = 0; i < ObjList.Count ; i++)
- {
- tempobj = ObjList[i];
- newPos = RadialArray(childPos[i], radius, radialRange, tempRow, rowMax, tempColumn, colMax);
- if (tempColumn==columns-1)
- {
- tempColumn = 0;
- tempRow++;
- }
- else
- {
- tempColumn++;
- }
- tempobj.Transform.localPosition = newPos;
- ObjFacing(tempobj);
- ObjList[i] = tempobj;
- }
- break;
- case GroupArrayTypes.Sphere:
- for (int i = 0; i < ObjList.Count ; i++)
- {
- tempobj = ObjList[i];
- newPos = SphereArray(childPos[i], radius);
- tempobj.Transform.localPosition = newPos;
- ObjFacing(tempobj);
- ObjList[i] = tempobj;
- }
- break;
- case GroupArrayTypes.Round:
- for (int i = 0; i < ObjList.Count; i++)
- {
- tempobj = ObjList[i];
- newPos = RoundArray( childPos[i],radius, i+1,ObjList.Count);
- newPos.Set(newPos.x+ChildOffsetX, newPos.y + ChildOffsetY, newPos.z +ChildOffsetZ);
- tempobj.Transform.localPosition = newPos;
- ObjFacing(tempobj);
- ObjList[i] = tempobj;
- }
- break;
- }
-
- }
- private Vector3 CylinderArray(Vector3 objPos,float radius)
- {
- float circ = 2.0f * Mathf.PI * radius;
- float xAngle = (objPos.x / circ) * 360f;
- objPos.Set(0.0f, objPos.y, radius);
- Quaternion rot = Quaternion.Euler(0.0f, xAngle, 0.0f);
- objPos = rot * objPos;
- return objPos;
- }
- private Vector3 SphereArray(Vector3 objPos, float radius)
- {
- float circ = 2.0f * Mathf.PI * radius;
- float XAngle = (objPos.x / circ) * 360f;
- float YAngle = -(objPos.y / circ) * 360f;
- objPos.Set(0.0f, 0.0f, radius);
- Quaternion rot = Quaternion.Euler(YAngle, XAngle, 0.0f);
- objPos = rot * objPos;
- return objPos;
- }
- private Vector3 RadialArray(Vector3 objPos, float radius ,float radialRange,int row,int rowMax,int column,int colMax)
- {
- float radialSpaceAngle = radialRange / colMax;
- objPos.Set(0.0f, 0.0f, (radius / rowMax) * row);
- float YAngle= radialSpaceAngle * (column - (colMax * 0.5f)) + (radialSpaceAngle * .5f);
- Quaternion rot = Quaternion.Euler(0.0f, YAngle, 0.0f);
- objPos = rot * objPos;
- return objPos;
- }
- private Vector3 RoundArray(Vector3 objPos , float radius,int i,int totalCount)
- {
- float angle = (360f *i )/ totalCount;
- float x = radius * Mathf.Cos(angle* Mathf.PI / 180f);
- float y = radius * Mathf.Sin(angle* Mathf.PI / 180f);
- objPos.Set(x,0,y);
- return objPos;
- }
- private void ObjFacing(GroupObj obj)//子物体的面向
- {
- Vector3 centerPos;
- Vector3 FacingNode;
- switch (FacingType)
- {
- case ObjFacingTypes.None:
- obj.Transform.transform.localEulerAngles = Vector3.zero;
- break;
- case ObjFacingTypes.FaceOrigin:
- obj.Transform.rotation = Quaternion.LookRotation(obj.Transform.position-transform.position,transform.up);
- break;
- case ObjFacingTypes.FaceOriginReversed:
- obj.Transform.rotation = Quaternion.LookRotation(transform.position- obj.Transform.position,transform.up);
- break;
- case ObjFacingTypes.FaceCenterAxis:
- centerPos = Vector3.Project(obj.Transform.position-transform.position,transform.up);//返回一个向量在指定轴上的投影
- FacingNode = transform.position + centerPos;
- obj.Transform.rotation = Quaternion.LookRotation(obj.Transform.position - FacingNode, transform.up);
- break;
- case ObjFacingTypes.FaceCenterAxisReversed:
- centerPos = Vector3.Project(obj.Transform.position - transform.position, transform.up);//返回一个向量在指定轴上的投影
- FacingNode = transform.position + centerPos;
- obj.Transform.rotation = Quaternion.LookRotation(FacingNode- obj.Transform.position , transform.up);
- break;
- case ObjFacingTypes.FaceParentDown:
- obj.Transform.forward = transform.rotation * Vector3.down;
- break;
- case ObjFacingTypes.FaceParentUp:
- obj.Transform.forward = transform.rotation * Vector3.up;
- break;
- case ObjFacingTypes.FaceParentFoward:
- obj.Transform.forward = transform.rotation * Vector3.forward;
- break;
- case ObjFacingTypes.FaceParentBack:
- obj.Transform.forward = transform.rotation * Vector3.back;
- break;
-
- }
- }
- private void setNull()
- {
- tempobj = null;
- childPos = null;
- }
- private void OnDestroy()
- {
- setNull();
- }
- }
|