Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. Dismiss Notice

Finding Closest Object with a choice of Two Tags

Discussion in 'Scripting' started by RaGEn, May 16, 2016.

  1. RaGEn

    RaGEn

    Joined:
    Feb 3, 2015
    Posts:
    88
    I`m trying to get my AI to find the closest enemy currently I have

    Code (CSharp):
    1. GameObject FindClosestEnemy()
    2.     {
    3.         GameObject[] gos;
    4.         gos = GameObject.FindGameObjectsWithTag("RedForces");
    5.         GameObject closest = null;
    6.         float distance = Mathf.Infinity;
    7.         Vector3 position = transform.position;
    8.         foreach (GameObject go in gos) {
    9.             Vector3 diff = go.transform.position - position;
    10.             float curDistance = diff.sqrMagnitude;
    11.             if (curDistance < distance) {
    12.                 closest = go;
    13.                 distance = curDistance;
    14.             }
    15.         }
    16.         return closest;
    17.     }
    However I want to add another faction named "Monsters". Is there a way to accomplish this without using a new function?
     
  2. Polymorphik

    Polymorphik

    Joined:
    Jul 25, 2014
    Posts:
    599
    You should never hardcode anything.

    This is Generic enough.

    Code (CSharp):
    1.     GameObject ClosestGO(Vector3 position, string tag) {
    2.         var objects = GameObject.FindGameObjectsWithTag(tag);
    3.  
    4.         GameObject closest = null;
    5.  
    6.         if(objects.Length > 0) {
    7.             closest = objects[0];
    8.             float smallestDistance = (closest.transform.position - position).magnitude;
    9.  
    10.             for(int i = 0; i < objects.Length; i++) {
    11.                 var possible = objects[i];
    12.  
    13.                 float distance = (possible.transform.position - position).magnitude;
    14.  
    15.                 if(distance < smallestDistance) {
    16.                     closest = possible;
    17.                     smallestDistance = distance;
    18.                 }
    19.             }
    20.         }
    21.  
    22.         return closest;
    23.     }
     
    Kiwasi likes this.
  3. RaGEn

    RaGEn

    Joined:
    Feb 3, 2015
    Posts:
    88
    I'm sorry I don't understand how that allow me to find the closest object with either "RedForces" or "Monsters"
     
  4. Kurt-Dekker

    Kurt-Dekker

    Joined:
    Mar 16, 2013
    Posts:
    36,370
    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."
     
    Kiwasi likes this.
  5. Polymorphik

    Polymorphik

    Joined:
    Jul 25, 2014
    Posts:
    599
    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'.