Finding Closest Object with a choice of Two Tags

I`m trying to get my AI to find the closest enemy currently I have

GameObject FindClosestEnemy()
    {
        GameObject[] gos;
        gos = GameObject.FindGameObjectsWithTag("RedForces");
        GameObject closest = null;
        float distance = Mathf.Infinity;
        Vector3 position = transform.position;
        foreach (GameObject go in gos) {
            Vector3 diff = go.transform.position - position;
            float curDistance = diff.sqrMagnitude;
            if (curDistance < distance) {
                closest = go;
                distance = curDistance;
            }
        }
        return closest;
    }

However I want to add another faction named ā€œMonstersā€. Is there a way to accomplish this without using a new function?

You should never hardcode anything.

This is Generic enough.

    GameObject ClosestGO(Vector3 position, string tag) {
        var objects = GameObject.FindGameObjectsWithTag(tag);

        GameObject closest = null;

        if(objects.Length > 0) {
            closest = objects[0];
            float smallestDistance = (closest.transform.position - position).magnitude;

            for(int i = 0; i < objects.Length; i++) {
                var possible = objects[i];

                float distance = (possible.transform.position - position).magnitude;

                if(distance < smallestDistance) {
                    closest = possible;
                    smallestDistance = distance;
                }
            }
        }

        return closest;
    }
1 Like

Iā€™m sorry I donā€™t understand how that allow me to find the closest object with either ā€œRedForcesā€ or ā€œMonstersā€

You might want to break the function out into two parts, as two serially-called ā€œhelperā€ functions.

helper function 1 takes a list of tags, such as ā€œRedForcesā€ and ā€œMonstersā€ (as a string array) and produces a single array (or list) containing ALL of the game objects that meet the tag criteria.

helper function 2 would accept a list of game objects and then iterate to find whatever you want to find out of them, like the closest, angriest, scariest, etc.

Look into using the List<> generic (gotta put a using System.Collections.Generic at the top of your script to use List<>) because you can grow that list in size (with the .AddRange() method on a List<>), whereas C# arrays are immutable in size once created.

Whatā€™s cool about the above is that if you want to do other things with ā€œFound lists of tagged enemiesā€ then you have a simple function you donā€™t have to rewrite.

Also, if you are able to obtain the list of enemies from somewhere else, you could still pass it to the second helper to ā€œfind closest.ā€

1 Like

Read the function header, the Vector3 is the relative position you want it to be closest to, the string tag is for your ā€˜RedForcesā€™ or ā€˜Monstersā€™.