geting the closest object from a array

hi i am making a tower defense game and i am working on the towers and i have a script that fills a array with all the enemies in the scene. but i want to know how to find the closest object in the array can anyone mod my script to work like that? here it is:

var target : Transform;
var enemies : GameObject[]; 
function Update () {
    enemies = GameObject.FindGameObjectsWithTag("enemy");
    transform.LookAt(target);

}

Sorry, I forgot mentioning that. To use GetKeyDown, you need a keycode (most probably). For example, if you want to press space to crouch write: Input.GetKeyDown(Keycode.Space) or for A Input.GetKeyDown(Keycode.A)

Hey Guys I think your Using The brackeys Tutorial you know he said to download the code In that code in Line 67 There will be line if (!crouch) If its like this remove The " ! " the result should be like if (crouch) This should do it my friend

2 Answers

2

It's not a good idea to use FindGameObjectsWithTag every frame, because it's slow. It's also a better idea to have enemies be a Transform array instead of a GameObject array, because that way you don't have to get the transform component every time you check the distance of one of them. The enemies array should only be rebuilt when necessary; it may be better to add and remove from an array instead of using Find at all, but that's a little more complicated.

Also, Vector3.Distance is a bit slow because it involves a square root; it's better to use (a-b).sqrMagnitude instead. Since a tower isn't going to move, it's better to store transform.position in a variable so you aren't constantly getting the transform component. As well, it's almost certainly not necessary to get the closest enemy every frame, so try to do that only as often as needed.

var target : Transform;
var myPosition : Vector3;
var enemies : Transform[];

function Start () {
    GetEnemies();
    myPosition = transform.position;
    target = FindClosest(enemies);
}

function GetEnemies () {
    var enemyObjects = GameObject.FindGameObjectsWithTag("enemy");
    enemies = new Transform[enemyObjects.Length];
    for (i = 0; i < enemyObjects.Length; i++) {
        enemies _= enemyObjects*.transform;*_
 _*}*_
_*}*_
_*function FindClosest (targets : Transform[]) : Transform {*_
 _*var closestDistance = (enemies[0].position - myPosition).sqrMagnitude;*_
 _*var targetNumber = 0;*_
 _*for (i = 1; i < targets.Length; i++) {*_
 <em>_var thisDistance = (enemies*.position - myPosition).sqrMagnitude;*_</em>
 <em>_*if (thisDistance < closestDistance) {*_</em>
 <em>_*closestDistance = thisDistance;*_</em>
 <em>_*targetNumber = i;*_</em>
 <em>_*}*_</em>
 <em>_*}*_</em>
 <em>_*return enemies[targetNumber];*_</em>
<em>_*}*_</em>
<em>_*```*_</em>
<em>_*<p>This way you can call the GetEnemies function only when needed, and the FindClosest function when appropriate (which depends on your game).  Since the function takes a Transform array as a parameter, it would be simple to have it check some enemy types but not others, as long as the different enemy types are in different Transform arrays.</p>*_</em>

in FindCloseset you pass targets : Transform[] but use enemies : Transform[], what is the deal with that?

@Pretender: what is the deal with what? I don't understand the question.

Hey, I found the mistake I have forgotten to select a layer for the Player and because of that the ground detection hasn´t worked right

You'll need to use Vector3.Distance:

var target : Transform; 
var enemies : GameObject[]; 

function Update () { 
    enemies = GameObject.FindGameObjectsWithTag("enemy"); 
    transform.LookAt(target);

    if(enemies.length > 0) {
        var closestEnemy = enemies[0];
        var dist = Vector3.Distance(transform.position, enemies[0].transform.position);

        for(var i=0;i<enemies;i++) {
            var tempDist = Vector3.Distance(transform.position, enemies*.transform.position);*
 *if(tempDist < dist) {*
 _closestEnemy = enemies*;*_
 _*}*_
 _*}*_
 _*//do something with the closestEnemy*_
 _*}*_
_*}*_
_*```*_

thanks a lot i'll try that

i got this error Assets/Scripts/dartTower.js(12,22): BCE0051: Operator '<' cannot be used with a left hand side of type 'int' and a right hand side of type '(UnityEngine.GameObject)'.

never mind i fixed the problem :) anyway it works great thanks!

for anybody else who gets that error... use for(var i=0; i < enemies.Length; i++) {

I don't know if you can see the submessages, so I will also share this as another message.