Allpurpose Function that finds closest GameObject with Component X
Hello!
I had a piece of code checking for the closest GameObject that has Component "Food" attached. Like this:
GameObject[] allobjects=(GameObject[])GameObject.FindObjectsOfType<Food>();
float closestdis=Mathf.Infinity;
GameObject closestFood=null;
foreach (GameObject t_object in allobjects) {
float dis=(transform.position-t_object.transform.position).magnitude;
if(dis<closestdis) {
closestdis=dis;
closestFood=t_object;
}
}
which worked fine. Now, I wanted to check for the closest GameObject that has the Component "Creature" attached. As this is more or less the same but with a different Component type, I tried to write a function that could find the closest GameObject with Component "x" attached. This function:
GameObject FindClosest (Type _component) {
GameObject[] allobjects=(GameObject[])GameObject.FindObjectsOfType(_component);
float closestdis=Mathf.Infinity;
GameObject closest=null;
foreach (GameObject t_object in allobjects) {
float dis=(transform.position-t_object.transform.position).magnitude;
if(dis<closestdis) {
closestdis=dis;
closest=t_object.gameObject;
}
}
return closest;
}
which is called by doing this:
GameObject closestfood=FindClosest(Food);
However, this doesn't work. Is what I want possible or do you have to copy and paste this code for every different ComponentType?
Answer by Bonfire-Boy · Jan 13, 2016 at 02:38 PM
If you're thinking about copying and pasting a bunch of code, just changing a type each time, chances are you want to be using Generics. Something like this...
GameObject FindClosest <TComponent>() where TComponent : MonoBehaviour
{
GameObject[] allobjects=(GameObject[])GameObject.FindObjectsOfType< TComponent>();
float closestdis=Mathf.Infinity;
GameObject closest=null;
foreach (GameObject t_object in allobjects) {
float dis=(transform.position-t_object.transform.position).magnitude;
if(dis<closestdis) {
closestdis=dis;
closest=t_object.gameObject;
}
}
return closest;
}
You'd call it using lines like
GameObject closestFood = FindClosest< Food >();
Awesome! This works perfectly. I rewrote the code to include a check if it doesn't find itself as closest, giving this a final (generic) way to solve this problem:
GameObject FindClosest<TComponent>() where TComponent : $$anonymous$$onoBehaviour {
TComponent[] allobjects=GameObject.FindObjectsOfType<TComponent>();
float closestdis=$$anonymous$$athf.Infinity;
GameObject closest=null;
foreach (TComponent t_object in allobjects) {
float dis=(transform.position-t_object.transform.position).magnitude;
if(dis<closestdis && !(t_object.gameObject==this.gameObject)) {
closestdis=dis;
closest=t_object.gameObject;
}
}
return closest;
}
Which is called with the line:
GameObject closestFood = FindClosest<Food>();
An alternative is to return the component ins$$anonymous$$d of the gameObject, that gives the following code:
TComponent FindClosest<TComponent>() where TComponent : $$anonymous$$onoBehaviour {
TComponent[] allobjects=GameObject.FindObjectsOfType<TComponent>();
float closestdis=$$anonymous$$athf.Infinity;
TComponent closest=null;
foreach (TComponent t_comp in allobjects) {
float dis=(transform.position-t_comp.transform.position).magnitude;
if(dis<closestdis && !(t_comp.gameObject==this.gameObject)) {
closestdis=dis;
closest=t_comp;
}
}
return closest;
}
Called using:
Food closestfood=FindClosest<Food>();
Answer by Tuncer · Jan 13, 2016 at 02:44 PM
Call :
GameObject closestfood=FindClosest(typeof(Food));
I tried this by calling:
GameObject closestfood2=FindClosest2 (typeof(Food));
with FindClosest2:
GameObject FindClosest2(Type t_component) {
GameObject[] allobjects=(GameObject[])GameObject.FindObjectsOfType(t_component);
float closestdis=$$anonymous$$athf.Infinity;
GameObject closest=null;
foreach (GameObject t_object in allobjects) {
float dis=(transform.position-t_object.transform.position).magnitude;
if(dis<closestdis && !(t_object.gameObject==this.gameObject)) {
closestdis=dis;
closest=t_object;
}
}
return closest;
}
But this gives an error I don't quite understand. This may still be a valid solution but it requires some more research. Error: InvalidCastException: Cannot cast from source type to destination type. Code line:
GameObject[] allobjects=(GameObject[])GameObject.FindObjectsOfType(t_component);
Your answer
