- Home /
how to find the closest (and second closest) object with tag - one object
Trying to find the closest enemy - the hidden player.
And find the next closest enemy can someone help me out
var hiddenplayer:GameObject;
var target:Transform;
enemies = GameObjectsWithTag("enemy");
if(enemies.length>0){
var closestEnemy=enemies[0];
var dist=Vector3.Distance(transform.position,enemies[0];
for (var i=0; i < enemies.Length; i++){
var tempDist=Vector3.Distance(transform.position,enemies[1].transform.position);
If(tempDist>dist){
closestEnemy }
target= closestEnemy;
Answer by Statement · Dec 17, 2013 at 12:55 AM
Read the docs on `GameObject.FindGameObjectsWithTag`.
The second example shows how to find the closest object tagged "Enemy".
Updated answer:
Here's an example I made that grabs all enemies and sorts all of them by distance.
From here, it should be easy for you to get the closest and the second closest one, and the third, fourth and the furthest one too. And everything in between.
// We can use a List, those can be sorted.
// So let's import System.Collections.Generic.
import System.Collections.Generic;
// The script starts by calling this:
// Just print the name of all enemies,
// sorted as closest to furthest.
PrintClosestEnemies();
function PrintClosestEnemies ()
{
// Get enemies as a list:
var array = GameObject.FindGameObjectsWithTag("Enemy");
var list = List.<GameObject>(array);
// Sort the list by distance from ourselves
list.Sort(ByDistance);
// Show the results;
// list[0] will be the closest,
// list[1] will be the second closest,
// list[2] will be the third closest,
// ... and so on.
for (var gameObject in list)
print(gameObject);
}
function ByDistance(a : GameObject, b : GameObject) : int
{
var dstToA = Vector3.Distance(transform.position, a.transform.position);
var dstToB = Vector3.Distance(transform.position, b.transform.position);
return dstToA.CompareTo(dstToB);
}
Sorry for the imcompele code but i couldnt post the whole thing but this code already finds the closest enemy what i was looking for is a way to find the second closest enemy
For the second closest enemy you would just need a bit of additional logic to keep track of the two closest distances ins$$anonymous$$d of just the first. Create an object reference to the second closest object and send that ins$$anonymous$$d of the first.
@rasheedqw if this is your real question please edit your question above to say so. This site has lots of people happy to help, but our answers are only as good as the questions they address.
Answer by KellyThomas · Dec 17, 2013 at 12:30 AM
You code snippet is incomplete and unformatted , you will need to fix that before we can provide further analysis.
From what we have:
var hiddenplayer:GameObject;
var target:Transform;
enemies =GameObjectsWithTag("enemy"); // Note 4
if(enemies.length>0){
var closestEnemy=enemies[0];
var dist=Vector3.Distance(transform.position,enemies[0]; // Note 1
for (var i=0; i < enemies.Length; i++) { // Note 2
var tempDist=Vector3.Distance(transform.position,enemies[1].transform.position);
If(tempDist < dist){ // Note 3
closestEnemy=enemies[i]; // Note 5
}
}
}
target=closestEnemy;
This line is missing a closing bracket
closestEnemy
is already set to enemies[0], the loop should be initialized withvar i = 1
so that comparisons are made with the next and subsequent items in the list."`if`" must not have a capital "`I`"., From here on I have tried to append the code from your comment below but my interpretation may not match your original code 1:1.
As @Statement points out this should be a call to
GameObject.FindGameObjectsWithTag()
You should also set
dist = tempDist
within this code block, this will update your search to test against the newly found closer distance.
Note that you mention hiddenplayer
in your question (and code) but your distance checks are relative to the gameObject this script is attached to. If you want these checks to be relative to hiddenPlayer
then change the first parameter of your Vector3.Distance()
calls to hiddenplayer.transform.position
Sorry i wrote the end twice but it would not post working off my phone and not computer spelled gameobject thing wrong try to post end of
closestEnemy=enemies[i]; } } target=closestEnemy;dist){
Answer by RyanZimmerman87 · Dec 17, 2013 at 03:04 AM
There is documentation for this kind of thing specifically.
But when trying to implement it within my project I got a lot of errors with their example. I'm still pretty new too programming so maybe I just screwed up the example implementation since I did this months ago. But here is a code example of what I am using in my project specifically. So it works for sure, but you will need to alter it for your specific use.
In this example you find the closest object of a certain tag and destroy it. You can easily modify the resulting logic of what happens with the closest logic, or what tags you use etc.
public GameObject playerObject;
GameObject closestObject;
public float distanceToDestroy = Mathf.Infinity;
//other variables here for other functionality in this script
void Start()
{
playerObject = GameObject.Find("Player");
//edit this variable if you want specific distances
//before performing logic (after finding closest)
distanceToDestroy = 0;
//I have other code here for functionality in this script
}
//finds closest object and returns it to destroyCLosestObject
GameObject findClosestVisibility()
{
GameObject[]objectArray;
objectArray = GameObject.FindGameObjectsWithTag("Arrow Tag");
float distance = Mathf.Infinity;
Vector3 position = playerObject.transform.position;
foreach(GameObject currentObject in objectArray)
{
Vector3 distanceCheck = currentObject.transform.position - position;
float currentDistance = distanceCheck.sqrMagnitude;
if (currentDistance < distance)
{
closestObject = currentObject;
distance = currentDistance;
}
}
return closestObject;
}
//call this function to find the closest object
//in this example it destroys it but it's not necessary to do so
public void destroyClosestObject()
{
findClosestVisibility();
//if you want additional logic checks do them here
//if not skip this and destroy
float finalDistanceCheck = Vector3.Distance (playerObject.transform.position, closestObject.transform.position);
if (finalDistanceCheck <= distanceToDestroy)
{
Destroy(closestObject);
}
}
}
Given how the Unity documentation didn't seem to work for me and gave errors I have no problem providing this example that should work correctly in C#
Hopefully I didn't leave anything out since I was kinda copy and pasting from my script so I may have missed a variable but hopefully not trying to do this fast!
Hope that helps!
This code already find the closest enemy perfectly i just need a way to find the second closest enemy
Answer by ta2909i · Apr 05, 2015 at 02:02 PM
Is this a bad way to targets with 1st and 2nd proximity?
I am simply:
Creating an Array with Targets as before (this time 'gos' add two target types just in case)
Then I am running the find first nearest function with the array as an input
I am running the find Second nearest function with the same array and another input to ignore the first nearest target...
function Update () {
var gos : GameObject[]; gos = GameObject.FindGameObjectsWithTag("Enemy Plane") + GameObject.FindGameObjectsWithTag("Enemy Land"); var first : GameObject = FindClosestEnemy (gos); var second : GameObject = Find2ndClosestEnemy (gos,first); print("1st "+first); print("2nd "+second); } function FindClosestEnemy (gos) : GameObject { var closest : GameObject; var distance = Mathf.Infinity; var position = transform.position; for (var go : GameObject in gos) { var diff = (go.transform.position - position); var curDistance = diff.sqrMagnitude; if (curDistance < distance) { closest = go; distance = curDistance; } } return closest; } function Find2ndClosestEnemy (gos, FirstNear) : GameObject{ var closest : GameObject; var distance = Mathf.Infinity; var position = transform.position; for (var go : GameObject in gos) { var diff = (go.transform.position - position); var curDistance = diff.sqrMagnitude; if (curDistance < distance && go !=FirstNear) { closest = go; distance = curDistance; } } return closest; }