How can I get my missile script to target the nearest tagged enemy?

Hey,

I’ve made a script in which I basically get the missile to target the gameobject tagged enemy and move towards it and destroy it. However I found that if you have multiple enemies in the scene it will not work. This is the code:

using UnityEngine;
using System.Collections;

public class Turret : MonoBehaviour {
	public Transform Enemy;

	void Start () 
	{
		Enemy = GameObject.FindGameObjectWithTag("Enemy");
	}

	void Update () 
	{
		float dist = Vector3.Distance(Enemy.transform.position,transform.position);
		if(dist <150)
		{
			transform.position = Vector3.MoveTowards(transform.position, Enemy.position, 60 * Time.deltaTime);
		}

	}
}

I understand that this will not work because there is more than one GameObject tagged “Enemy” But I don’t understand how to get around this? How can i tweek this so it fires towards the nearest tagged enemy within 150 units.

Many thanks in advance

Okay Guys I fixed this with my own script, I’m adding this to the post so people can use this as a learning resource.

using UnityEngine;
using System.Collections;
using System.Collections.Generic;

public class Turret : MonoBehaviour {
	public List <Transform> Enemies;
	public Transform SelectedTarget;

	void Start () 
	{
		SelectedTarget = null;
		Enemies = new List<Transform>();
		AddEnemiesToList();
	}

	public void AddEnemiesToList()
	{
		GameObject[] ItemsInList = GameObject.FindGameObjectsWithTag("Enemy");
		foreach(GameObject _Enemy in ItemsInList)
		{
			AddTarget(_Enemy.transform);
		}
	}

	public void AddTarget(Transform enemy)
	{
		Enemies.Add(enemy);
	}

	public void DistanceToTarget()
	{
		Enemies.Sort(delegate( Transform t1, Transform t2){ 
			return Vector3.Distance(t1.transform.position,transform.position).CompareTo(Vector3.Distance(t2.transform.position,transform.position)); 
		});
	
	}

	public void TargetedEnemy() 
	{
		if(SelectedTarget == null)
		{
			DistanceToTarget();
			SelectedTarget = Enemies[0];
		}
	
	
	}

	void Update () 
	{
		TargetedEnemy();
		float dist = Vector3.Distance(SelectedTarget.transform.position,transform.position);
		//if(dist <150)
		//{
			transform.position = Vector3.MoveTowards(transform.position, SelectedTarget.position, 60 * Time.deltaTime);
		//}

	}
}

There is an article on unity gems that has an elegant solution for this problem, but it’s using Linq :

link text

The advantage is that it takes a very few lines to do it, just add at the top of your script :

//C#
using System.Collections.Generic; //Always a good idea
using System.Linq;
 
//JavaScript
import System.Linq;

And where you want to make your detection :

//C#
 
var closestGameObject = GameObject.FindGameObjectsWithTag("MyTag")
    .OrderBy(go => Vector3.Distance(go.transform.position, transform.position)
    .FirstOrDefault();
 
//Javascript
 
var closestGameObject = GameObject.FindGameObjectsWithTag("MyTag")
    .OrderBy(function (go) Vector3.Distance(go.transform.position, transform.position))
    .FirstOrDefault();

The only downside is that the code above doesn’t take maximal distance of 150 units into account, but if you look at their article, there is some exemples that use this kind of distance limitation.

If you don’t want to learn Linq, just add a distance check on the closestGameObject that it returns. Something like :

float dist = Vector3.Distance(closestGameObject.transform.position,transform.position);

if(dist <= 150)
// Do Something

This script works for me however the only problem comes when the object is destroyed. Since it has nothing to destroy. It errors out.