Wayback Machinekoobas.hobune.stream
May JUN Jul
Previous capture 12 Next capture
2021 2022 2023
1 capture
12 Jun 22 - 12 Jun 22
sparklines
Close Help
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
  • Asset Store
  • Get Unity

UNITY ACCOUNT

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account
  • Blog
  • Forums
  • Answers
  • Evangelists
  • User Groups
  • Beta Program
  • Advisory Panel

Navigation

  • Home
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
    • Blog
    • Forums
    • Answers
    • Evangelists
    • User Groups
    • Beta Program
    • Advisory Panel

Unity account

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account

Language

  • Chinese
  • Spanish
  • Japanese
  • Korean
  • Portuguese
  • Ask a question
  • Spaces
    • Default
    • Help Room
    • META
    • Moderators
    • Topics
    • Questions
    • Users
    • Badges
  • Home /
avatar image
0
Question by kenw21901 · Feb 26, 2017 at 01:05 PM · c#arraylistdistanceloop

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!

Comment
Add comment
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users

2 Replies

· Add your reply
  • Sort: 
avatar image
3

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

Comment
Add comment · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image
0

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];
 }
Comment
Add comment · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users

Your answer

Hint: You can notify a user about this post by typing @username

Up to 2 attachments (including images) can be used with a maximum of 524.3 kB each and 1.0 MB total.

Follow this Question

Answers Answers and Comments

9 People are following this question.

avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image

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


Enterprise
Social Q&A

Social
Subscribe on YouTube social-youtube Follow on LinkedIn social-linkedin Follow on Twitter social-twitter Follow on Facebook social-facebook Follow on Instagram social-instagram

Footer

  • Purchase
    • Products
    • Subscription
    • Asset Store
    • Unity Gear
    • Resellers
  • Education
    • Students
    • Educators
    • Certification
    • Learn
    • Center of Excellence
  • Download
    • Unity
    • Beta Program
  • Unity Labs
    • Labs
    • Publications
  • Resources
    • Learn platform
    • Community
    • Documentation
    • Unity QA
    • FAQ
    • Services Status
    • Connect
  • About Unity
    • About Us
    • Blog
    • Events
    • Careers
    • Contact
    • Press
    • Partners
    • Affiliates
    • Security
Copyright © 2020 Unity Technologies
  • Legal
  • Privacy Policy
  • Cookies
  • Do Not Sell My Personal Information
  • Cookies Settings
"Unity", Unity logos, and other Unity trademarks are trademarks or registered trademarks of Unity Technologies or its affiliates in the U.S. and elsewhere (more info here). Other names or brands are trademarks of their respective owners.
  • Anonymous
  • Sign in
  • Create
  • Ask a question
  • Spaces
  • Default
  • Help Room
  • META
  • Moderators
  • Explore
  • Topics
  • Questions
  • Users
  • Badges