Using generics as variable types in Unity

Viewed 2661

I wish to change the following code so I could pass a parameter of type T or Component in this function such that it can be used in the type arguments. This would be used in place of ButtonManager in the following code, Is this possible? Could I use generics to accomplish this? I wish to do this so I can reuse this method for a variety of Component types, vice having to make a method per component type.

private GameObject[] FindInActiveObjectsByType()
    {
        List<GameObject> validTransforms = new List<GameObject>();
        ButtonManager[] objs = Resources.FindObjectsOfTypeAll<ButtonManager>() as ButtonManager[];
        for (int i = 0; i < objs.Length; i++)
        {
            if (objs[i].hideFlags == HideFlags.None)
            {
                objs[i].gameObject.GetComponent<ButtonManager>().ConfigureInteractives();
                validTransforms.Add(objs[i].gameObject);
            }
        }
        return validTransforms.ToArray();
    }
2 Answers

You are already using the generic overload Resources.FindObjectsOfTypeAll<T>() which always returns T[]

In order to make the rest (e.g. GetComponent) work you only have to make sure that T is always of type Component so you would do

public GameObject[] YourMethod<T>() where T : Component
{
    List<GameObject> validTransforms = new List<GameObject>();
    T[] objs = Resources.FindObjectsOfTypeAll<T>();
    for (int i = 0; i < objs.Length; i++)
    {
        if (objs[i].hideFlags == HideFlags.None)
        {
            //objs[i].gameObject.GetComponent<T>().ConfigureInteractives();
            validTransforms.Add(objs[i].gameObject);
        }
    }
    return validTransforms.ToArray();
}

Note however that ConfigureInteractives() seems to be specificly related to your ButtonManager and will throw an exception since it is not part of Component.

So in case you need this for other stuff inheriting from ButtonManager then simply exchange the Component with ButtonManager in

public void YourMethod<T>() where T : ButtonManager

How could I check the passed in Type

There are multiple ways. You could e.g. check the exact passed type using

if(typeof(T) == typeof(ButtonManager)) (objs[i].gameObject.GetComponent<T>() as ButtonManager).ConfigureInteractives();

but then you could also simply g back to using

if(typeof(T) == typeof(ButtonManager)) objs[i].gameObject.GetComponent<ButtonManager>().ConfigureInteractives();

or you could use maybe typeof(T).IsSubclassOf(typeof(ButtonManager)) for also matching inherited types.

Sure, you can do the following:

public void YourFunction<T>() where T : Component
{
    T component = gameObject.GetComponent<T>();
}
Related