How to create a generic monobehavior referencer

Hello everyone,

I have a question that, although I consider somewhat basic, can’t seem to either find online or figure out.
Let’s say I have a prefab “A” and it has two children Gameobjects, (a light and an audiosource). After instantiating this prefab, I would like to reference both elements so I can, for example, dim the lights. Now, there are several ways I know you can go about doing that: using transform.find and/or FindWithTag are both usable methods, but that I tend to avoid them since they are slow and not very robust. My default “go to” method would be to create a component attached to A, that has references to both things, the light and the source.

public class PrefabAReferencer : MonoBehaviour
{
    public Light m_Light;
    public AudioSource m_Audiosource;
}

Now, this works just fine and allows me to access stuff pretty efficiently, but I dislike having to create a new file for references every time I create a new prefab (or, for that matter, having to update the reference script if, for example, I add a new children to prefab A).

I would like to create a script that I could attach to a Gameobject and that had a reference to any other component. My initial idea was to use generics since they are exactly the way I would go about solving this issue. Something like:

public class GenericReferencer<T> : MonoBehaviour
{
    public T m_Ref;
}

Now, sadly, that wont be displayed on the inspector since Unity has not way to know the type of T and cant properly serialize the class. I can create a class that inherits from GenericReferencer, using a concrete type, but then I run into the same problem of needing to do this for every new type I need.

The best solution I have managed to come up with is to just have an Unity Object as the reference and then access it whenever needed, doing a cast for the desired type. Although this solution works, I would still like to have a little bit more of robustness by having the Type explicitly stated on the referencer.

Is there any way to do something similar to what I’m trying to? Thanks for the help :slight_smile:

Isn’t this what GetComponentInChildren<T> does?


If your children are different for each game object then I think you are going to have to write different code to ideally reference them. At least one for every variation.

i.e. if you have a bunch of different prefabs with the same configuration of children then you could use the same script but as soon as they differ you will have to differentiate the code.


The only other way to do it would be to stick them in a collection but that in itself would require a bunch of faff with constantly casting them to the derived type you want instead of to their base component type.

Granted this could be abstracted away but the performance overhead cant really be and at that point all you have done is create a less efficient version of GetComponentInChildren()


What is it that you are trying to solve here? If it’s trying to have global references to certain objects you can definitely achieve that in a bunch of ways from static references to DI’ing references to them.


I am still not sure what you are trying to achieve but maybe if you are sold on this pattern interfaces with extension methods may help?

i.e. you could have an empty ILightable interface which had a GetLights() extension method.

Then all you would need to do is add ILightable to your class and it would give you access to that method on any instances of it.

Something like:


public interface ILightable {}

public static class ReferenceExtensions
{
    public static Light GetLight(this MonoBehaviour mb) 
    {
        return mb.gameObject.GetComponentInChildren<Light>();
    }
}

public class GenRefTest : MonoBehaviour, ILightable
{
    void Update()
    {
        var lights = this.GetLight();
    }
}



public class AnotherGenRefTest : MonoBehaviour, ILightable
{
    void Update()
    {
        var lights = this.GetLight();
    }
}