Find closest script

I need to find the closest gameobject with a specific scrip attached to it, and then store the gameobject that I found in a varieble. It would be good if it didn’t use the update function sins I only need to find it once, and I don’t want to waste any preformance.
If anyone have any idea of how to do that and could leave an example (I prefer C#) that would be grate.

will this object have its own tag or name?

I will assume it does and pretend the tag is ‘ThingWithScript’

You can use the old 'FindClosestEnemy()’ ploy

And just call it once in the Start()

And use gos = GameObject.FindGameObjectsWithTag(“ThingWithScript”);

You’ll need to include:

using System.Collections.Generic;
using System.Linq;

This function (call it whenever you please, perhaps at start) will get the closest gameobject that has YOURSCRIPT attached:

private GameObject GetClosestGuy(){
		//empty dictionary
		Dictionary<GameObject, float> listofguys = new Dictionary<GameObject, float>();

		//add all the gameobjects that have your script
		foreach ( GameObject o in FindObjectOfType( typeof (YOURSCRIPT) ) as GameObject ){
			float dist = Vector3.Distance( o.transform.position, transform.position );
			listofguys.Add(o, dist);
		}

		//sort them by distance with linq
		List<GameObject> sortedbydist = listofguys.OrderByDescending(x => x.Value).Select(p => p.Key).ToList();

		//return the last object in the sorted list (which is the smallest distance)
		return sortedbydist[sortedloaders.Count()-1];
	}

Its untested. Probably has a bug somewhere but something like that.

Just a quick sketchup of what it might look like… I am at work so I can’t test it, but if you want to do it outside of the Update function, then you could use the Start function. Otherwise, you could use a bool to make it run only once. Suppose the script you are looking for is called ABC.

GameObject GO;

void Start()
{
     Collider[] myArray = Physics.CheckSphere(transform.position, 10.0f);
     PickObject(myArray);
}

void PickObject(Collider[] colliders)
{
    foreach(Collider myCollider in colliders)
    {
       if(myCollider.GetComponent(ABC))
         {
            GO = myCollider.gameObject;
         }
    }
}

If all you want is the closest then the Dictionary is unnecessary as is the sorting. Also - if you’re just comparing distances you can use squared distance and save a square root operation.

That doesn’t get the closest object.

MyScript[] scripts = FindObjectsOfType(typeof(MyScript)) as MyScript[];
float dist = float.MaxValue;
MyScript closest;
for (int i = 0; i < scripts.Length; i++)
{
    float d = (transform.position - scripts[i].transform.position).sqrMagnitude;
    if (d < dist)
    {
        dist = d;
        closest = scripts[i];
    }
}

Yay, I learned something new! I never would have thought to just compare against itself in a loop like that. I’ve got some code to change.