KamikyIT
KamikyIT

Reputation: 314

Find all gameojects with components of base class

I have the base class derived from MonoBehaviour

public abstract class AbstractMyGameBeh : MonoBehaviour{//....}

And many other classes, realising this base class.

public class MyGameBeh: AbstractMyGameBeh {//....}
public class BMyGameBeh: AbstractMyGameBeh {//....}
public class CMyGameBeh: AbstractMyGameBeh {//....}

So now I need to find all gameobjects of this classes. Ofcource, I can do like this, but if I make more classes derived from AbstractMyGameBeh, I'll be have to fix this code part again.

GameObject.FindObjectsOfType<AMyGameBeh>()
GameObject.FindObjectsOfType<BMyGameBeh>()
GameObject.FindObjectsOfType<CMyGameBeh>()

Upvotes: 0

Views: 255

Answers (2)

Liquid Core
Liquid Core

Reputation: 1

C# 6.0 allows the use of

typeof

if(objOfTypeMyGameBeh.GetType() == typeof(AbstractMyGameBeh))
{
 //It's the type you want
}
else
{
//it's not the type you want
}

or as

 if(objOfTypeMyGameBeh as AbstractMyGameBeh != null)
    {
     //It's the type you want, works aswell with inheritance
    }
    else
    {
    //it's not the type you want
    }

That should work and you can put it in a loop pretty easily to check every object.

As pointed out in the comments, if you're not storing the value you can use is keyword

Upvotes: 1

Kooooons
Kooooons

Reputation: 109

I've had a similar Problem recently and this solution might be applicable to your problem:

    public static IEnumerable<Type> GetTypes()
    {

        var sourceAssembly = Assembly.GetCallingAssembly();
        var assemblies = new List<Assembly>();
        assemblies.AddRange(sourceAssembly.GetReferencedAssemblies().Select(an => Assembly.Load(an)));
        assemblies.Add(sourceAssembly);

        var subclassTypes = new HashSet<Type>();
        foreach (var assembly in assemblies)
        {
            var types = assembly.GetTypes().Where(t => t.IsSubclassOf(typeof(AbstractMyGameBeh)));
            foreach (var type in types) subclassTypes.Add(type);
        }
        return subclassTypes;
    }

This should work even if your AbstractMyGameBeh is in a different Assembly as long as you call it from an assembly where all child classes are available.

It will search all assemblies (the calling one and all that are referenced by it) for heir classes of your abstract class.

Now This leaves you with a set of Types. So you'd still need to use reflection to call GameObject.FindObjectsOfType<T>(). Should be something like this...

foreach(var subclassType in subclassTypes)
{
     MethodInfo method = GetType("GameObject").GetMethod("FindObjectsOfType")
                                              .MakeGenericMethod(new Type[] { subclassType });
     method.Invoke(gameObject, new object[] { });
}

Upvotes: 0

Related Questions