Как я могу рассчитать и создать позиции треугольной формы? - PullRequest
0 голосов
/ 06 ноября 2018
private void FormationTriangle()
{
    newpositions = new List<Vector3>();
    for (int x = 0; x < squadMembers.Count; x++)
    {
        for (int y = x; y < 2 * (squadMembers.Count - x) - 1; y++)
        {
            Vector3 position = new Vector3(x, y);
            newpositions.Add(position);
        }
    }

    move = true;
    formation = Formation.Square;
}

Циклы неправильные. Это поместило состав членов в одну линию один над другим. Даже близко к форме треугольника. Я хочу, чтобы члены отряда стояли в форме треугольника.

Это движущаяся часть: Но проблема в том, что петли вычисляют позиции в форме треугольника. Другие формирования, которые я сделал, работают нормально.

private void MoveToNextFormation()
{
    if (randomSpeed == false)
    {
        if (step.Length > 0)
            step[0] = moveSpeed * Time.deltaTime;
    }

    for (int i = 0; i < squadMembers.Count; i++)
    {
        squadMembers[i].transform.LookAt(newpositions[i]);
        if (randomSpeed == true)
        {
            squadMembers[i].transform.position = Vector3.MoveTowards(
                squadMembers[i].transform.position, newpositions[i], step[i]);
        }
        else
        {
            squadMembers[i].transform.position = Vector3.MoveTowards(
                squadMembers[i].transform.position, newpositions[i], step[0]);
        }
        if (Vector3.Distance(squadMembers[i].transform.position, newpositions[i]) < 
            threshold)
        {
            if (squareFormation == true)
            {
                Vector3 degrees = new Vector3(0, 0, 0);
                Quaternion quaternion = Quaternion.Euler(degrees);
                squadMembers[i].transform.rotation = Quaternion.Slerp(
                    squadMembers[i].transform.rotation, quaternion, 
                    rotateSpeed * Time.deltaTime);
            }
            else
            {
                squadMembers[i].transform.rotation = Quaternion.Slerp(
                    squadMembers[i].transform.rotation, quaternions[i], 
                    rotateSpeed * Time.deltaTime);
            }
        }
    }
}

Ответы [ 2 ]

0 голосов
/ 06 ноября 2018

Этот ответ создаст треугольник, устроенный так:

    x
   x x
  x x x
 x x x x
x x x x x 

Или, если недостаточно для заполнения полного треугольника:

    x
   x x
  x x x
 x x x x
x   x   x 

Поскольку вам не гарантировано совершенно треугольное количество единиц, вам следует переоценить, насколько велик ваш треугольник, вести подсчет количества единиц, которые вы поместили, и затем прекратить их размещение, когда вы достигнете своего предела.

Сначала найдите высоту наименьшего треугольного числа, превышающую ваше число единиц, и само это треугольное число :

int height = Mathf.CeilToInt( (Mathf.Sqrt(8*squadMembers.Count+1f)-1f)/2 ) 
int slots = (int)(height * (height+1f)/2f)

Затем найдите положение первого подразделения. Нам нужно знать сколько у нас рядов слотов и какова ширина нижнего ряда слотов:

float verticalModifier = 0.8f;  // 0.8f to decrease vertical space
float horizontalModifier = 1.25f; // 1.25f to increase horizontal space

float width = 0.5f * (height-1f);
Vector3 startPos = new Vector3(width* horizontalModifier, 0f, (float)(height-1f) * verticalModifier);

Затем добавляйте, пока не добавите достаточно

int finalRowCount = height - slots + squadMembers.Count;
for (int rowNum = 0 ; rowNum < height && newpositions.Count < squadMembers.Count; rowNum++) {
    for (int i = 0 ; i < rowNum+1 && newpositions.Count < squadMembers.Count ; i++ ) {
        float xOffset = 0f;

        if (rowNum+1 == height) {
            // If we're in the last row, stretch it ...
            if (finalRowCount !=1) {
                // Unless there's only one item in the last row. 
                // If that's the case, leave it centered.

                xOffset = Mathf.Lerp(
                        rowNum/2f,
                        -rowNum/2f,
                        i/(finalRowCount-1f)
                        ) * horizontalModifier;
            }
        }
        else {
            xOffset = (i-rowNum /2f) * horizontalModifier; 
        }

        float yOffset = (float)rowNum * verticalModifier; 

        Vector3 position = new Vector3(
                startPos.x + xOffset, 0f, startPos.y - yOffset);
        newpositions.Add(position);

    }
}
0 голосов
/ 06 ноября 2018

Посмотрим, что содержит список позиций для простого значения, n = 3

Сначала цикл x от 0 до 2 (3 - 1) Затем для каждого x, цикл от x до 4-x (3*2 - x - 1 - 1)
Помня, что a<b совпадает с a<=b-1

Это дает нам ...

0,0
0,1
0,2
0,3
0,4
1,1
1,2
1,3
2,2

Каких позиций много. Конечно, может занять более 3 единиц! По крайней мере, это треугольник:

X\Y 0  1  2  3  4  
0   #  #  #  #  #  
1      #  #  #  
2         #  

Основная проблема в том, что вы генерируете способов * на 1020 * больше позиций, чем необходимо, и ожидаете как-то заполнить их.

Вам необходимо рассчитать ширину и высоту на основе формулы площади для треугольника: A = (b*h)/2, и вы можете даже захотеть b=h, где A = number of units.

Итак, как-то так:

int b = Mathf.CeilToInt(Mathf.Sqrt(squadMembers.Count));
    for (int x = 0; x < b; x++)
    {
        //the divide by 2 is accounted for with this 2*
        for (int y = x; y < 2 * (b - x) - 1; y++)
        {
            Vector3 position = new Vector3(x, y);
            newpositions.Add(position);
        }
    }
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...