- Home /
What's the best way to find the smallest Vector3.Distance of an array of enemies?
I'm still relatively new to programming. I've only been taught c#, so please keep answers in c#. I've already filled the array with FindGameObjectsOfType, and have the distance updating each frame, but I can't figure out how to keep the array's organized by indexer AND seeing which enemy is closest at any given time. I've seen a way to reorganize the list of floats by smallest to largest, but I was hoping to keep the indexes between my enemy array and my distance list the same so I could activate a boolean on the enemy that marks it as the closest enemy.
My end goal is to have one single enemy on the entire enemy array marked as the closest enemy. My code so far is in my player's data model:
public EnemyDataModel[] enemys;
public List<float> enemyDistances = new List<float>();
public int index = 0;
void Start()
{
enemys = GameObject.FindObjectsOfType<EnemyDataModel>();
for(int i = 0; i < enemys.Length; i++)
{
enemys[i].name = enemys[i].name + i.ToString();
enemys[i].GetComponent<EnemyDataModel>().nameIndex = i;
enemyDistances.Add(Vector3.Distance(transform.position, enemys[i].transform.position);
}
}
void EnemyProximityCheck()
{
if(index < enemys.Length)
{
enemyDistances[index] = Vector3.Distance(transform.position, enemys[index].transform.position);
index++;
}
else
{
index = 0;
}
}
Like I said before, this at least gets an updated distance per frame for each enemy in my array. And enemyDistances[0] belongs to enemys[0] and so on. How can I compare all the distances in the enemyDistances list, and be able to tell which enemy in the enemys array the smallest distance belongs to? I am open to any possible solutions.
I've thought about sorting the list from smallest to largest float, but that would mess up the indexer and I wouldn't be able to tell which enemy has the smallest distance. I so badly want to hard code everything and just manual type in a float variable for each member of the array that I'll know will be in the array, but I know it'd be better this way in case my level design changes. I've also thought of just typing in an if statement for every possible comparison but that seems like an exorbitant amount of code. There's gotta be a better way. Please help!
Answer by IgorAherne · Feb 26, 2017 at 01:27 PM
enemys[i].GetComponent<EnemyDataModel>()
is redundant, you are already pointing at EnemyDataModel
when you acces [i]
cell.
WHat you have is simmilar to this.transform.transform
, so there is no need to getComponent.
Now as to your question, just use linq:
using System.Linq;
EnemyDataModel closestEnemy = enemys.Min(e => (e.transform.position - transform.position).magnitude);
we just took your entire enemies array and got one entry which had minimum distance in the entire array.
we used e
as an abbreviation of enemy. Linq is quite clever to understand that e
means EnemyDataModel
, since that's what enemys[]
stores anyway.
To improve performance use .squareMagnitude
instead of .magnitude
Answer by ByteSheep · Feb 26, 2017 at 01:35 PM
If you only need to find the nearest enemy then you shouldn't need to keep an array of distances. You can simply store the smallest distance found so far like this:
public EnemyDataModel[] enemies;
private void Start()
{
var nearestEnemy = GetNearestEnemy();
// Do something with this enemy
}
private EnemyDataModel GetNearestEnemy()
{
float minDist = float.MaxValue;
int nearestIndex = -1;
for (int i = 0; i < enemies.Length; i++)
{
var dist = Vector3.Distance(transform.position, enemies[i].transform.position);
if (dist < minDist)
{
nearestIndex = i;
minDist = dist;
}
}
return nearestIndex == -1 ? null : enemies[nearestIndex];
}
Your answer
Follow this Question
Related Questions
How to check if the string is on a text file 0 Answers
Remove object from List after gameObject was destroyed in between Scene loads 1 Answer
Copy From Array to List without reference [C#] 2 Answers
How to compare and detect overlapping gameObject Prefabs using maths 0 Answers
Saving and applying an array of Vector3 velocities on an array of GameObjects 1 Answer