/// <summary> /// Align all transforms position with one Transform, or on mini/max values of boundaries /// </summary> /// <param name="referenceTransform"> /// A <see cref="Transform"/> which all other transforms will be aligned with, if alignType is "mean" /// </param> /// <param name="transformList"> /// The <see cref="Transform[]"/> of all objects to be aligned /// </param> /// <param name="axis"> /// The axis to align on : <see cref="Vector3.one"/> to align all axis, <see cref="Vector3.right"/> to align on the X axis, <see cref="Vector3.up"/> to align on the Y axis, <see cref="Vector3.forward"/> to align on the Z axis /// </param> /// <param name="alignType"> /// Witch type of alignement we do, from the <see cref="Landmark"/> enum /// </param> public static void AlignPosition(Transform referenceTransform, Transform[] transformList, Vector3 axis, Landmark alignType, ExtentsGetter.BoundType boundType) { //bool useBounds = (alignType != Landmark.distributed && alignType != Landmark.mean); // Get the position from the active selected object Vector3 markPosition = referenceTransform.position; // If alignment is not the mean one, search the min or max positioned object if (alignType == Landmark.minimum) { markPosition = ExtentsGetter.GetMinMarkPosition(referenceTransform.position, transformList, boundType); } else if (alignType == Landmark.maximum) { markPosition = ExtentsGetter.GetMaxMarkPosition(referenceTransform.position, transformList, boundType); } Vector3 activePosition = markPosition; foreach (Transform nextTransform in transformList) { Vector3 newPos; Vector3 delta = Vector3.zero; if (alignType == Landmark.maximum) { if (nextTransform.GetComponent <Renderer>()) { delta = -nextTransform.GetComponent <Renderer>().bounds.extents; } else if (nextTransform.GetComponent <Collider>()) { delta = -nextTransform.GetComponent <Collider>().bounds.extents; } } else if (alignType == Landmark.minimum) { if (nextTransform.GetComponent <Renderer>()) { delta = nextTransform.GetComponent <Renderer>().bounds.extents; } else if (nextTransform.GetComponent <Collider>()) { delta = nextTransform.GetComponent <Collider>().bounds.extents; } } // refers to axisList : None, X, Y, Z, All -> 0, 1, 2, 3, 4 newPos.x = (axis == Vector3.one || axis == Vector3.right) ? activePosition.x + delta.x : nextTransform.position.x; newPos.y = (axis == Vector3.one || axis == Vector3.up) ? activePosition.y + delta.y : nextTransform.position.y; newPos.z = (axis == Vector3.one || axis == Vector3.forward) ? activePosition.z + delta.z : nextTransform.position.z; nextTransform.position = newPos; } }
/// <summary> /// Grid position distribution with full parameters /// </summary> /// <param name="activeTransform"> /// The <see cref="Transform"/> that other transforms will be aligned to, if requested /// </param> /// <param name="transformList"> /// All <see cref="Transform[]"/> to be distributed /// </param> /// <param name="gridSize"> /// The grid size in a <see cref="Vector3"/> so the objects can be distributed in cells /// </param> public static void DistributePositionInGrid(Transform activeTransform, Transform[] transformList, Vector3 gridSize) { if (transformList.Length == 0) { return; } // Get the min and max marks Vector3 minMarkPosition = ExtentsGetter.GetMinMarkPosition(activeTransform.position, transformList, ExtentsGetter.BoundType.None); Vector3 maxMarkPosition = ExtentsGetter.GetMaxMarkPosition(activeTransform.position, transformList, ExtentsGetter.BoundType.None); // List of selected objects, to sort from the min position to the max position List <Transform> list = new List <Transform>(transformList); int gridCount = list.Count; // the distance between each cell is calculated from the min and max positionned objects Vector3 distanceBetween = Vector3.one; distanceBetween.x = (gridSize.x > 1 ? ((maxMarkPosition.x - minMarkPosition.x) / (gridSize.x - 1)) : 0); distanceBetween.y = (gridSize.y > 1 ? ((maxMarkPosition.y - minMarkPosition.y) / (gridSize.y - 1)) : 0); distanceBetween.z = (gridSize.z > 1 ? ((maxMarkPosition.z - minMarkPosition.z) / (gridSize.z - 1)) : 0); Vector3 newPos = Vector3.zero; Transform nextTransform = null; for (int i = 0; i < gridCount; i++) { nextTransform = list[i]; newPos = nextTransform.position; if (gridSize.x > 0) { newPos.x = Mathf.RoundToInt((nextTransform.position.x - minMarkPosition.x) / distanceBetween.x) * distanceBetween.x + minMarkPosition.x; } if (gridSize.y > 0) { newPos.y = Mathf.RoundToInt((nextTransform.position.y - minMarkPosition.y) / distanceBetween.y) * distanceBetween.y + minMarkPosition.y; } if (gridSize.z > 0) { newPos.z = Mathf.RoundToInt((nextTransform.position.z - minMarkPosition.z) / distanceBetween.z) * distanceBetween.z + minMarkPosition.z; } nextTransform.position = newPos; } }
/// <summary> /// Linear Position Distribution with full parameters /// </summary> /// <param name="activeTransform"> /// The <see cref="Transform"/> that other transforms will be aligned to, if requested /// </param> /// <param name="transformList"> /// All <see cref="Transform[]"/> to be distributed /// </param> /// <param name="sortBy"> /// The axis which is used to sort the transform list, <see cref="SortAxis"/> /// </param> /// <param name="axis"> /// The axis to distribute the transforms on, using the same <see cref="Vector3"/> format /// </param> public static void DistributePosition(Transform activeTransform, Transform[] transformList, SortAxis sortBy, Vector3 axis) { if (transformList.Length == 0) { return; } // Get the min and max marks (no bounds here since it would make the ends go farer) Vector3 minMarkPosition = ExtentsGetter.GetMinMarkPosition(activeTransform.position, transformList, ExtentsGetter.BoundType.None); Vector3 maxMarkPosition = ExtentsGetter.GetMaxMarkPosition(activeTransform.position, transformList, ExtentsGetter.BoundType.None); // Interval Vector3 distanceBetween = (maxMarkPosition - minMarkPosition) / (transformList.Length - 1); // Delta from minMark Vector3 delta = Vector3.zero; // List of selected objects, to sort from the min position to the max position List <Transform> list = new List <Transform>(transformList); // Sort the selected objects from their position (only one axis is taken into account) switch (sortBy) { case SortAxis.Z: list.Sort(ByVector3PositionZ); break; case SortAxis.Y: list.Sort(ByVector3PositionY); break; default: list.Sort(ByVector3PositionX); break; } foreach (Transform nextTransform in list) { Vector3 newPos; newPos.x = (axis == Vector3.one || axis == Vector3.right) ? minMarkPosition.x + delta.x : nextTransform.position.x; newPos.y = (axis == Vector3.one || axis == Vector3.up) ? minMarkPosition.y + delta.y : nextTransform.position.y; newPos.z = (axis == Vector3.one || axis == Vector3.forward) ? minMarkPosition.z + delta.z : nextTransform.position.z; nextTransform.position = newPos; delta += distanceBetween; } }