Exemplo n.º 1
0
    // Find the closest fit for units into a bounding area, scaling the size of the units and finding optimal layout
    // in the bounding area. Moves the units to the bounding area once a size is found
    private void LayoutArmy(float overSeconds = 0)
    {
        mInvaderControllerDimensions  = InvaderPrefab.GetComponent <RectTransform>().rect.size;
        mInvaderControllerDimensions += Vector3.one * 20 * 2f;
        float prefabScale    = 1f;
        float unitsPerColumn = 0;
        int   numArchers     = mInvaderControllers[InvaderType.Archer].Count;
        int   numHealers     = mInvaderControllers[InvaderType.Healer].Count;
        int   numSoldiers    = mInvaderControllers[InvaderType.Soldier].Count;
        int   errorBreak     = 10; // upper limit of resizing

        while (errorBreak-- > 0)
        {
            unitsPerColumn = Mathf.FloorToInt(BoundingArea.y / mInvaderControllerDimensions.y);
            if (unitsPerColumn == 0)
            {
                unitsPerColumn = 1;
                prefabScale    = mInvaderControllerDimensions.y / BoundingArea.y;
                mInvaderControllerDimensions *= prefabScale;
            }
            float numColumns = Mathf.Ceil(numArchers / unitsPerColumn);
            numColumns += Mathf.Ceil(numHealers / unitsPerColumn);
            numColumns += Mathf.Ceil(numSoldiers / unitsPerColumn);

            float totalWidthNeeded = numColumns * mInvaderControllerDimensions.x;
            float difference       = (BoundingArea.x - totalWidthNeeded) / BoundingArea.x;
            if (difference < 0)
            {
                prefabScale /= 1 + (Mathf.Abs(difference) / 2f);
                mInvaderControllerDimensions /= 1 + (Mathf.Abs(difference) / 2f);
            }
            else
            {
                break;
            }
        }
        // place soldiers
        int count       = 0;
        int columnCount = 0;

        InvaderType[] invaderOrderings = { InvaderType.Archer, InvaderType.Healer, InvaderType.Soldier };
        for (int typeIdx = 0; typeIdx < invaderOrderings.Length; typeIdx++)
        {
            List <InvaderController> controllers = mInvaderControllers[invaderOrderings[typeIdx]];
            foreach (InvaderController controller in controllers)
            {
                if (count == unitsPerColumn)
                {
                    count = 0;
                    columnCount++;
                }
                controller.transform.localScale = Vector3.one * prefabScale;
                Vector3 positionInArmy = new Vector3(columnCount * mInvaderControllerDimensions.x, -count * mInvaderControllerDimensions.y);
                if (overSeconds > 0)
                {
                    controller.MoveToPosition(transform.position + positionInArmy, overSeconds);
                    //controller.transform.localPosition = positionInArmy;
                }
                else // set at position
                {
                    controller.transform.position = transform.position + positionInArmy;
                }

                count++;
            }
            // started a new column but didn't finish it. Add rest to next wave
            if (count > 0)
            {
                count = 0;
                columnCount++;
            }
        }
    }