/// <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;
        }
    }