【发布时间】:2021-02-06 00:33:44
【问题描述】:
我有这个类的列表:
public class EachEnemy
{
public GameObject enemy;
public Vector3 coords;
public float distance;
}
他们会计算到船的“距离”。 随着敌人的生成和移动,距离变量一直在变化。
我需要在该类的列表中找到最小的距离,以及它的索引,以便我可以瞄准 Enemy 对象。
【问题讨论】:
我有这个类的列表:
public class EachEnemy
{
public GameObject enemy;
public Vector3 coords;
public float distance;
}
他们会计算到船的“距离”。 随着敌人的生成和移动,距离变量一直在变化。
我需要在该类的列表中找到最小的距离,以及它的索引,以便我可以瞄准 Enemy 对象。
【问题讨论】:
你可以用Linq OrderBy点赞
using System.Linq;
...
// Wherever you get this from
List<EachEnemy> allEnemies;
// Sorted by the distance to this object
var sortedEnemies = allEnemies.OrderBy(enemy => (transform.position - enemy.coords).sqrMagnitude);
// Or depending on how your class is used simply
//var sortedEnemies = allEnemies.OrderBy(enemy => enemy.distance);
// This would return null if the list was empty
// Or the first element of the sorted lost -> smallest distance
var nearestEnemy = sortedEnemies.FirstOrDefault();
注意使用
OrderBy(enemy => (transform.position - enemy.coords).sqrMagnitude);
会比首先实际计算距离更有效,因为它会跳过对所有向量 sqrMagnitudes 使用平方根。因为a > b 也暗示了a² > b²,并且我们知道幅度总是正的,所以知道所有增量向量的sqrMagnitudes 就足以对它们进行排序。
这样做的好处是你还可以获得第二和第三近的敌人等。
【讨论】:
float smallestDistance = eachEnemyList[0].distance;
int index = 0;
for(int i = 1; i < eachEnemyList.Count; i++)
{
if(eachEnemyList[i].distance < smallestDistance)
{
smallestDistance = eachEnemyList[i].distance;
index = i;
}
}
这可能没有完美优化,但应该没问题。这为您提供了最小距离和包含最小距离的 EachEnemy 类的索引。
【讨论】:
您可以遍历列表中的每个项目并在循环外保存值,也可以将索引保存在循环外,例如
EachEnemy someFuncname(List<EachEnemy> list)
{
int index = 0;
EachEnemy ea = null;
float distance = 9999 ///
foreach (var Enemy in list) {
if (Enemy.Distance < distance) {
ea = Enemy;
}
return ea;
}
同样的方法也可以返回索引。
【讨论】: