Creating a single-line function for GameObject.Find and GetComponent (for multiple components)

Hi, all, this is my first time asking a question on UnityAnswers. I’ve been here plenty of times and it’s been a very useful resource so far, and now that I’ve got an account, hopefully I can start giving back to the community.

On with my question: up until recently I’ve been getting by with a single function, activated in the Awake function, which finds each and every object needed by the script and its’ GameObject:

public GameObject cwGO;
public GUIText cwTx;

void FindObjects()
    {
        cwGO = GameObject.Find("CurWep");
        cwTx = cwGO.GetComponent<GUIText>();
    }

void Awake()
    {
        FindObjects();
        setVars();
    }

and as you can see, another function to set the variables.

What I’m trying to figure out is a way of condensing GameObject.Find and GetComponent to a single line and activating one function for each object I’m attempting to find. This is what I have so far:

void objF(GameObject gO, string gOs, Component cmp, Component typ)
    {
        gO = GameObject.Find(gOs);
        cmp = gO.GetComponent<typ>();
    }

My end goal would be something like this:

objF(cwGO, "CurWep", cwTx, GUIText);

However, what I have isn’t working: the second instance of ‘typ’ (GetComponent()) is throwing up an error. What should the datatype(s) be so that this function will work, if it could work?

Help would be appreciated, thanks.

EDIT:

void objF(GameObject gO, string gOs, Component cmp, *datatype* *variable*)
        {
            gO = GameObject.Find(gOs);
            cmp = gO.GetComponent<*variable*>();
        }

In order to be able to include any datatype that can be found using ‘GetComponent’ (box colliders, sphere colliders, GUIText and even C# scripts), what should be entered in the spaces marked variable and datatype? As of now I’m limited to only ever being able to find a single type of component, be it GUIText, colliders or the like: I’d like to make this function universal so that I can find any type of component by entering it in the brackets when calling the function:

objF(cwGO, "CurWep",cwTx, *any component*);

The arguments (variables passed to objF) do not retain values that you pass into the function unless you mark the argument with the keyword “ref” in both the definition and wherever you call the function.

 void objF(ref GameObject gO, string gOs, ref Component cmp, Component typ)
{
      gO = GameObject.Find(gOs);
      cmp = gO.GetComponent<typ>();
}

And you would call it like this:

objF(ref cwGO, "CurWep", ref cwTx, GUIText);

Bare in mind that there are much better ways of doing this than using “GameObject.Find” as it can be very expensive at run time depending on the size of your game, it might be better to utilize Singletons. (Implementing Singleton in C# | Microsoft Learn)

You probably want to be using generics:

public static void FindObject<T>(string name, ref GameObject go, ref T component) where T : Component
{
    go = GameObject.Find(name);
    component = go.GetComponent<T>();
}

Called like this:

FindObject("CurWep", ref cwGO, ref cwTx);

But like DFortun81 said, GameObject.Find() calls are costly, so be careful, especially if calling every frame.

Implementing Gizmoi’s solution into my code:

public static void objF<typ>(ref GameObject gO, string gOs, ref typ cmp) where typ : Component
        {
            gO = GameObject.Find(gOs);
            cmp = gO.GetComponent<typ>();
    
            print("object found");
        }

It’s called like this:

objF<GUIText>(ref cwGO, "CurWep", ref cwTx);

Looks like it’s working now. You missed the instance of ‘GUIText’ between ‘FindObject’ and the parameters, but I figured it out, added it in and the function is working now.

Thanks for your help, much appreciated.