Detecting Enemy Distance via List

I have been attempting to create a system that detects all enemies inside a sphere collider and calculates their distance. So far, I have this which grabs all the objects and puts them in to a list, this works good.

private void OnTriggerEnter(Collider other)
    {


        if (HitBoxAI.isENEMY) {
            if (other.tag == "Friendly")
            {
                if (!targets.Contains(other.gameObject))
                {
                    targets.Add(other.gameObject);
                }
            }
            if (other.tag == "Player")
            {
                if (!targets.Contains(other.gameObject))
                {
                    targets.Add(other.gameObject);
                }
            }
        }
        if (HitBoxAI.isALLY)
        {
            if (other.tag == "Enemy")
            {
                if (!targets.Contains(other.gameObject))
                {
                    targets.Add(other.gameObject);
                }
            }
        }

Now, that all works and successfully adds the gameobjects into the list.

What do I want?

I want to make it so that I can run a function that will look through the list and determine the closest game object in the list to the current transform.gameObject and then to assign the AI’s target to that.

So, as for pseudocode, I am trying to achieve something like;

ai.target = targets.closestInList

I can imagine another way would be using the List.Sort method and then just making the target the first in the index such as [0]. My experience with lists unfortunatetly is not very good, I hope someone can give a helping hand.

Many thanks.

I do this a lot for my game, i’m happy to share it to you if it can help you :wink: It’s pretty simple.

float distance = 0;
GameObject closestTarget;
for (int i = 0; i < targets.Length; i++)
{
	float targetDistance = Vector3.Distance (transform.position, targets *.transform.position);*
*	if (targetDistance < distance || i == 0)*
*	{*
_		closestTarget = targets *;*_
_*		distance = targetDistance;*_
_*	}*_
_*}*_
_*ai.target = closestTarget;*_
_*```*_
_*I hope it help, Sean.*_

You will have to loop through your list. Keeping track of which object has the lowest distance from the target object.

    using System.Collections;
    using System.Collections.Generic;
    using UnityEngine;
    
    public class Example : MonoBehaviour {
    
        public List<GameObject> targets;//This is your list fill it with the objects you want to test.
        public GameObject NearestEnemyObject;// This will hold our result of our closest target at the end
        public GameObject ObjectToCompareTo;// This you will need to have declared as your object you want to be your center point.
        public float closestTarget;// used to detect the first run of our foreach loop below.
    
    	// Use this for initialization
    	void Start () {
    
           closestTarget = 0.0f;//Set to 0 so we can force the first run of the loop to catch our distance values.
    
            ///Assuming your list is already populated in this script before this point....
            foreach (GameObject TargetObjectToTestDistance in targets)
            {
                if (closestTarget == 0.0f)//Only happens on first run as we are about to set below. We need to have at least one distance calculation before we can compare that vs the other objects in list.
                {
                    closestTarget = Vector3.Distance(TargetObjectToTestDistance.transform.position, ObjectToCompareTo.transform.position);//Since we are in our fist run store the distance of the first object of our list
                    NearestEnemyObject = TargetObjectToTestDistance;//Go ahead and set our NearestEnemy variable incase the first object is the closes out of all.
                }
                else//this will trigger every run after the first since distance should never return 0.0f unless you test 2 objects in the same x,y,z location.
                {
                    if (Vector3.Distance(TargetObjectToTestDistance.transform.position, ObjectToCompareTo.transform.position) < closestTarget)//test to see if each following object's distance is lower than our current lowest distance result
                    {
                        closestTarget = Vector3.Distance(TargetObjectToTestDistance.transform.position, ObjectToCompareTo.transform.position);//if the object was closer update our closest distance float so our next loop run will test vs this.
                        NearestEnemyObject = TargetObjectToTestDistance;//Since we are closer than any object before go ahead and store the gameobject for later use.
    
                    }
                }
    
            }
            //Now that our loop has finished iterating through all our list objects we should have overwritten NearestEnemyObject with the closet target enemy of all from our list
Debug.Log("Closest object is. " + NearestEnemyObject.name.toString());
        }
    
    }

This is just a rough example. But if you populate the list with some objects. Then set your object to test against through inspector you should end up with the name of the closest object in debug.