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.