Search Unity

How to: Get all components on an object that implement an interface.

Discussion in 'Editor & General Support' started by cerebrate, Aug 17, 2011.

  1. cerebrate

    cerebrate

    Joined:
    Jan 8, 2010
    Posts:
    261
    so, say you have a monobehaviour that implements an Interface, and you want to get all the scripts that implement that interface, kind of like so:

    gameObject.GetComponents<interfaceClass>();

    this will not work, as GetComponent (and it's variants for children and stuff) requires that the type be of type Component.

    The other problem is that interfaces cannot inherit, so you can't just make the interface inherit from component.

    solution: Get all the scripts on the object, then go through them, seeing if they implement the interface type with reflection.

    this is using linq by the way, so make sure you stick a 'using System.Linq' at the top of the script.
    Code (csharp):
    1.  
    2. var mObjs = menuObject.GetComponents<MonoBehaviour>();
    3. InterfaceType[] interfaceScripts = (from a in mObjs where a.GetType().GetInterfaces().Any(k => k == typeof(InterfaceType)) select (InterfaceType)a).ToArray();
    4.  
    why use this?

    Speed. If you have an array of references to interface-implementing scripts, you can now call methods on scripts much faster than using SendMessage. However, this only works if you set the array in an Awake or Start. Using all of this code every time you want to do a sendmessage will be just as slow, if not slower.

    Code (csharp):
    1.  
    2. foreach (var iScript in interfaceScripts)
    3. {
    4.    iScript.SomeMethod();
    5. }
    6.  
    Edit:

    Have some extension methods:

    Code (csharp):
    1.  
    2. using System;
    3. using UnityEngine;
    4. using System.Linq;
    5.  
    6. public static class GameObjectExtensions
    7. {
    8. /// <summary>
    9.     /// Returns all monobehaviours (casted to T)
    10.     /// </summary>
    11.     /// <typeparam name="T">interface type</typeparam>
    12.     /// <param name="gObj"></param>
    13.     /// <returns></returns>
    14.     public static T[] GetInterfaces<T>(this GameObject gObj)
    15.     {
    16.         if (!typeof(T).IsInterface) throw new SystemException("Specified type is not an interface!");
    17.         var mObjs = gObj.GetComponents<MonoBehaviour>();
    18.  
    19.         return (from a in mObjs where a.GetType().GetInterfaces().Any(k => k == typeof(T)) select (T)(object)a).ToArray();
    20.     }
    21.  
    22.     /// <summary>
    23.     /// Returns the first monobehaviour that is of the interface type (casted to T)
    24.     /// </summary>
    25.     /// <typeparam name="T">Interface type</typeparam>
    26.     /// <param name="gObj"></param>
    27.     /// <returns></returns>
    28.     public static T GetInterface<T>(this GameObject gObj)
    29.     {
    30.         if (!typeof(T).IsInterface) throw new SystemException("Specified type is not an interface!");
    31.         return gObj.GetInterfaces<T>().FirstOrDefault();
    32.     }
    33.  
    34.     /// <summary>
    35.     /// Returns the first instance of the monobehaviour that is of the interface type T (casted to T)
    36.     /// </summary>
    37.     /// <typeparam name="T"></typeparam>
    38.     /// <param name="gObj"></param>
    39.     /// <returns></returns>
    40.     public static T GetInterfaceInChildren<T>(this GameObject gObj)
    41.     {
    42.         if (!typeof(T).IsInterface) throw new SystemException("Specified type is not an interface!");
    43.         return gObj.GetInterfacesInChildren<T>().FirstOrDefault();
    44.     }
    45.  
    46.     /// <summary>
    47.     /// Gets all monobehaviours in children that implement the interface of type T (casted to T)
    48.     /// </summary>
    49.     /// <typeparam name="T"></typeparam>
    50.     /// <param name="gObj"></param>
    51.     /// <returns></returns>
    52.     public static T[] GetInterfacesInChildren<T>(this GameObject gObj)
    53.     {
    54.         if (!typeof(T).IsInterface) throw new SystemException("Specified type is not an interface!");
    55.  
    56.         var mObjs = gObj.GetComponentsInChildren<MonoBehaviour>();
    57.  
    58.         return (from a in mObjs where a.GetType().GetInterfaces().Any(k => k == typeof(T)) select (T)(object)a).ToArray();
    59.     }
    60. }
    61.  
    use:

    InterfaceType[] interfaces = gameObject.GetInterfaces<InterfaceType>();
     
    Last edited: Aug 17, 2011
  2. newborne

    newborne

    Joined:
    Jul 16, 2012
    Posts:
    31
    thanks!
     
  3. Good_Venson

    Good_Venson

    Joined:
    Oct 12, 2014
    Posts:
    22
    Oh, Thanks so much! I found this and just about got depressed lol =P
     
  4. dc5774

    dc5774

    Joined:
    Feb 1, 2014
    Posts:
    16
    Unity is also the name for Microsoft's dependency injection framework. It's all way above my head.