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;
}
循环是错误的。它将squadMembers放置在一条线中,另一条线上方。 甚至不接近三角形。 我希望squadMembers呈三角形。
这是运动的部分:但是问题出在计算三角形位置的循环上。我做过的其他编队都很好。
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);
}
}
}
}
答案 0 :(得分:6)
让我们看看职位列表包含一个简单值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 #
主要问题是,您生成的方式头寸超出了所需,并希望以某种方式填补。
您需要根据三角形的面积公式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);
}
}
答案 1 :(得分:5)
由于不能保证三角形的单位数完美,因此您应该高估三角形的大小,计算已放置的单位数,然后在达到极限时放弃放置。
int height = Mathf.CeilToInt( (Mathf.Sqrt(8*squadMembers.Count+1f)-1f)/2 )
int slots = (int)(height * (height+1f)/2f)
然后,找到第一个单元的位置。我们需要知道how many rows个插槽以及插槽底部的行宽:
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);
}
}