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

C# trying to find closest target with same tag

Discussion in 'Scripting' started by TheLLaMaHiMseLF, Aug 3, 2014.

  1. TheLLaMaHiMseLF

    TheLLaMaHiMseLF

    Joined:
    Sep 7, 2013
    Posts:
    3
    OK so, although I am a noob, i managed to get this far without learning how to find the closest tagged target lol.

    Basically, what I am doing here is I attach this script to a vehicle, and if the vehicle is within a certain range of the target, then it sends a message to my enemy script which destroys that game object and enables a ragdoll to take its place. Yes, I am running people over :D .

    It works good with a single enemy (still a little buggy but that will be ironed out soon), but when I add multiple enemies (the goal is a near infinite amount of enemies), it does not target the "closest" enemy, and although I have Gooooogled my butt off, I cannot find a solution that makes sense to me (lack of sleep could be playing a factor.)

    Here is my code so far:

    Code (CSharp):
    1.  
    2. using UnityEngine;
    3. using System.Collections;
    4.  
    5. public class HitByCar : MonoBehaviour {
    6.  
    7.     public float damage = 100; //amount of damage to inflict
    8.     public float distance; //distance to target
    9.     public float maxDistance = 5.0f; //when target is in damage range
    10.     public GameObject Target; //current target
    11.    
    12.     void Update () {
    13.         //find target with tag
    14.         Target = GameObject.FindGameObjectWithTag("Enemy");
    15.        
    16.         //find distance to target
    17.         distance = Vector3.Distance(transform.position, Target.transform.position);
    18.        
    19.         //if within damaging range
    20.         if(distance < maxDistance ){
    21.        
    22.         //send message to targets script
    23.         Target.SendMessage("ApplyDamage", damage);  
    24.  
    25.         }
    26.  
    27.     }
    28.  
    29. }
    30.  
    Thank you for any help in advance, I wouldn't have made it this far without these forums. :)
    -Chris
     
  2. smitchell

    smitchell

    Joined:
    Mar 12, 2012
    Posts:
    702
    Unity has a example in the docs doing exactly what you want: http://docs.unity3d.com/ScriptReference/GameObject.FindGameObjectsWithTag.html

    Code (CSharp):
    1. GameObject FindClosestEnemy() {
    2.         GameObject[] gos;
    3.         gos = GameObject.FindGameObjectsWithTag("Enemy");
    4.         GameObject closest;
    5.         float distance = Mathf.Infinity;
    6.         Vector3 position = transform.position;
    7.         foreach (GameObject go in gos) {
    8.             Vector3 diff = go.transform.position - position;
    9.             float curDistance = diff.sqrMagnitude;
    10.             if (curDistance < distance) {
    11.                 closest = go;
    12.                 distance = curDistance;
    13.             }
    14.         }
    15.         return closest;
    16.     }
     
    Guidi500 likes this.
  3. smitchell

    smitchell

    Joined:
    Mar 12, 2012
    Posts:
    702
    So in your code you'd set Target to FindClosestEnemy ();
     
  4. TheLLaMaHiMseLF

    TheLLaMaHiMseLF

    Joined:
    Sep 7, 2013
    Posts:
    3
    Thank you, its funny cause i looked at that a few times and it didn't make sense how i would implement it, BUT now it makes perfect sense :p
     
  5. ChadrickEvans

    ChadrickEvans

    Joined:
    Mar 14, 2015
    Posts:
    46
    I still don't quite understand this. I know it's a year old but I'm completely stumped on which line of code goes where...
     
  6. vothka

    vothka

    Joined:
    Mar 27, 2015
    Posts:
    59
    just copy/pasting what i already told someelse who was looking for a solution of finding the largest number in an array.

    this can be very comfortably achieved with Linq as you can put all this stuff in one single line, which still looks (more or less) readable

    Code (CSharp):
    1. //add the namespace
    2. using System.Linq;
    3.  
    4. GameObject GetNearestTarget()
    5. {
    6. //so lets say you want the closest target from a array (in this case all Gameobjects with Tag "enemy") and let's assume this script right now is on the player (or the object with which the distance has to be calculated)
    7. return GameObject.FindGameObjectsWithTag("enemy").Aggregate((o1, o2) => Vector3.Distance(o1.transform.position, this.transform.position) > Vector3.Distance(o2.transform.position, this.transform.position) ? o2 : o1);
    8. }
    9.  
    10.  
    this does the whole job, it iterates through your array, picks the 2 objects o1 and o2 and returns the smaller one (in this case)

    so just to break it down a bit
    "?" is called ternary operator which can be used instead of "if"

    so if you want to know which number is larger you could write
    Code (CSharp):
    1.  
    2. int a = 2;
    3. int b = 3;
    4. int higherNumber;
    5.  
    6. //now you could write
    7. if (a > b)
    8. higherNumber = a;
    9. else
    10. higherNumber = b;
    11.  
    12.  
    13. //or
    14. higherNumber = a > b ? a : b;
    and Aggregate does it the same way. Take two elements, compare them to a spcified criteria, which is a comparison of Vector3.Distance in this case, and return the smaller one
     
    Last edited: Apr 20, 2015
    rndrobin likes this.
  7. ChadrickEvans

    ChadrickEvans

    Joined:
    Mar 14, 2015
    Posts:
    46
    Thanks for the reply, however, I have multiple enemies (about 20 in-game)

    I'm just trying to get a better understanding of where this code should be placed in my script.
     
  8. KashXP

    KashXP

    Joined:
    Apr 16, 2021
    Posts:
    2
    how would you go about setting the target to that
     
  9. Joe-Censored

    Joe-Censored

    Joined:
    Mar 26, 2013
    Posts:
    11,847
    Code (csharp):
    1. Target = FindClosestEnemy();