[SOLVED] Passing component as System.Type as argument (Unity 5 relevant)

I want to pass a component by System.Type as argument into a function. Strings are not allowed any longer in Unity5. But that works well.

void SelectGOByComponent(System.Type SourceComponent) {}

Then using FindObjectsOfType(SourceComponent) as SourceComponent[ ]) to find all objects in a for each loop. But this didn’t work for the compiler.

void SelectGOByComponent(System.Type SourceComponent) {
    foreach (var GO in FindObjectsOfType(typeof(SourceComponent)) as SourceComponent[]) {
    }
}

I’m not finding a way to do correctly. Does anyone how to?
Thanks

SourceComponent is already a type you don’t need to put typeof around it.

1 Like

typeof turns the keyword for the class into an object representation of the class definition… a System.Type.

You already have the System.Type in your SelectGOByComponent, no need to typeof it.

1 Like

Yes, I was irritated because of requiring as SourceComponent[ ] to get any internal array in var GO like this example.

foreach (var AnyGo in FindObjectsOfType(typeof(GameObject)) as GameObject[]) {
}

Now works simply. Thanks a lot to you both.

void SelectGOByComponent(System.Type SourceComponent) {
        foreach (var OBJ in FindObjectsOfType(SourceComponent)) {
              // OBJ is a Type Object only.
        }
    }

Sometimes a bit quirky…
How can I cast GO to a GameObject to access as default?
foreach (var GO in FindObjectsOfType(SourceComponent) as GameObject)
foreach (GameObject GO in FindObjectsOfType(SourceComponent))
or var g = (GameObject)GO;
doesn’t work again :-/

foreach ( ??? GO in FindObjectsOfType(SourceComponent)) {
         }

The method doesn’t know the return type at compile time since the type is a variable.

But all unity objects inherit from the type UnityEngine.Object, so they’re returned as that.

You can cast to some type you know they are after that… if you know the type going in. In your case you know it’s going to be a Component, so you can cast it to Component. (or at least I assume, since you named the variable ‘SourceComponen’).

1 Like

Thanks again.

void SelectGOByComponent(System.Type SourceComponent) {
            foreach (Component GO in FindObjectsOfType(SourceComponent)) {
                  // GO is a GameObject
            }
        }

The easiest way would be to use generics, but that’s not always possible. So I just wanted to ask whether this could be an option?

Yes, I want to sort GOs by name and component into other game objects with a specified name and components.
If you have working generic example for the upper one would be great. Is there any benefit in a generic solutions?

With generics, there are often fewer type casts. And if you try to avoid them, the overall design becomes often more maintainable.

WARNING: UNTESTED CODE

void SelectGOByComponent <T> () where T : MonoBehaviour {
    foreach (T yourComponent in FindObjectsOfType <T>()) {
        // yourComponent can directly be used or yourComponent.gameObject if you need the game object of it.
    }
}
1 Like

Thanks I will have a try :slight_smile: