Wayback Machinekoobas.hobune.stream
May JUN Jul
Previous capture 13 Next capture
2021 2022 2023
1 capture
13 Jun 22 - 13 Jun 22
sparklines
Close Help
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
  • Asset Store
  • Get Unity

UNITY ACCOUNT

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account
  • Blog
  • Forums
  • Answers
  • Evangelists
  • User Groups
  • Beta Program
  • Advisory Panel

Navigation

  • Home
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
    • Blog
    • Forums
    • Answers
    • Evangelists
    • User Groups
    • Beta Program
    • Advisory Panel

Unity account

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account

Language

  • Chinese
  • Spanish
  • Japanese
  • Korean
  • Portuguese
  • Ask a question
  • Spaces
    • Default
    • Help Room
    • META
    • Moderators
    • Topics
    • Questions
    • Users
    • Badges
  • Home /
avatar image
0
Question by DarKAeRiX · Jan 11, 2015 at 06:24 PM · c#gameobjectgetcomponentfind

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*);




Comment
Add comment · Show 1
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image DoubleIsLoveDoubleIsLife · Jan 13, 2015 at 12:14 AM 0
Share

$$anonymous$$onoBehaviour?

3 Replies

· Add your reply
  • Sort: 
avatar image
1
Best Answer

Answer by Gizmoi · Jan 20, 2015 at 03:27 PM

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.

Comment
Add comment · Show 2 · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image DarKAeRiX · Jan 20, 2015 at 04:24 PM 0
Share

$$anonymous$$y implementation of this will be up in a bit (I credited you in the answer). Have a look.

By the way, I had a look at DFortun81's alternative to GameObject.Find calls, which was the use of Singletons. However, according to $$anonymous$$icrosoft's database, Singletons are out of date. I know that I can tag every object that I'd like to find using the function and then use FindGameObjectsWithTag, but are there any alternatives out there? I've scoured the internet for solutions and not had much luck.

avatar image Gizmoi · Jan 20, 2015 at 04:30 PM 0
Share

I wouldn't say Singletons are out of date, but they're not a solution for everything either.

Generally I make sure everything is parented to a single root object in each scene. And let each $$anonymous$$onoBehaviour attached to an object find its own children.

For example, I have a 'GUI' object in most scenes, with a specific script depending on the type of GUI that it is. This script finds all its children that it needs in Awake and then other scripts further up in the hierarchy can modify them, post-Awake.

avatar image
1

Answer by DFortun81 · Jan 13, 2015 at 12:26 AM

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. (http://msdn.microsoft.com/en-us/library/ff650316.aspx)

Comment
Add comment · Show 3 · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image DarKAeRiX · Jan 19, 2015 at 03:23 PM 0
Share

Hi, apologies for the delay in answering and thanks for the input.

I attempted the supplied method and have a similar error this time around. The 'typ' keyword is still throwing up an error, but now, so is the calling of the function in its entirety.

I'm going to rephrase the question a little to generalise it more for any datatype, not just GUIText. The edited question will be above.

avatar image DFortun81 · Jan 20, 2015 at 02:13 AM 0
Share

I figured that you called the type "typ", but reading through this again points to it ins$$anonymous$$d as a "I want to get a specific type of component from the game object with the name contained in the gOs variable".

To do that, all you have to do is pass the Type ins$$anonymous$$d of the component and then the format of the cmp assignment line. (See this for reference: http://docs.unity3d.com/ScriptReference/GameObject.GetComponent.html)

 // Use this to call the function with a System.Type:
 // objF(ref cwGO, "CurWep", ref cwTx, typeof(GUIText));
 void objF(ref GameObject gO, string gOs, ref Component cmp, Type typ)
 {
     gO = GameObject.Find(gOs);
     cmp = gO.GetComponent(typ);
 }
 
 // Use this to call the function with a string:
 // objF(ref cwGO, "CurWep", ref cwTx, "GUIText");
 void objF(ref GameObject gO, string gOs, ref Component cmp, string typ)
 {
     gO = GameObject.Find(gOs);
     cmp = gO.GetComponent(typ);
 }

I've posted examples on how to use it in the comment directly above each function.

avatar image DarKAeRiX · Jan 20, 2015 at 03:04 PM 0
Share

I followed both methods, and the first one required me to declare 'typ' as datatype 'Type'. 'Type' isn't a datatype according to C#, so I used the closest option available, 'Types'. This caused an error for the following:

'static types cannot be used as parameters'

 gO.GetComponent(typ);

 
 

in

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

 
 

I then tried the second method, which worked great when declaring the function (no errors here):

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

  
 

but when I attempted to write the code to invoke it:

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

 
 

Error CS1503: Argument 3 cannot convert UnityEngine.GUIText expression to type 'UnityEngine.Component'

The final parameter won't take. If I try and directly solve the cause of the error, I'll only be converting the GUIText string to Component, so what I need to be able to do now is to convert any string that goes into the space for the final parameter, all of which will be component names in String format, to a component. Any ideas?

avatar image
0

Answer by DarKAeRiX · Jan 20, 2015 at 04:16 PM

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.

Comment
Add comment · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users

Your answer

Hint: You can notify a user about this post by typing @username

Up to 2 attachments (including images) can be used with a maximum of 524.3 kB each and 1.0 MB total.

Follow this Question

Answers Answers and Comments

5 People are following this question.

avatar image avatar image avatar image avatar image avatar image

Related Questions

Getcomponent error? 1 Answer

How to run a function in a GO that have DontDestroyOnLoad 1 Answer

C# GetComponent / change values throught other script 3 Answers

Null Reference Exception Help 1 Answer

fix script to get C# var from another object instead of object this script is attached to 2 Answers


Enterprise
Social Q&A

Social
Subscribe on YouTube social-youtube Follow on LinkedIn social-linkedin Follow on Twitter social-twitter Follow on Facebook social-facebook Follow on Instagram social-instagram

Footer

  • Purchase
    • Products
    • Subscription
    • Asset Store
    • Unity Gear
    • Resellers
  • Education
    • Students
    • Educators
    • Certification
    • Learn
    • Center of Excellence
  • Download
    • Unity
    • Beta Program
  • Unity Labs
    • Labs
    • Publications
  • Resources
    • Learn platform
    • Community
    • Documentation
    • Unity QA
    • FAQ
    • Services Status
    • Connect
  • About Unity
    • About Us
    • Blog
    • Events
    • Careers
    • Contact
    • Press
    • Partners
    • Affiliates
    • Security
Copyright © 2020 Unity Technologies
  • Legal
  • Privacy Policy
  • Cookies
  • Do Not Sell My Personal Information
  • Cookies Settings
"Unity", Unity logos, and other Unity trademarks are trademarks or registered trademarks of Unity Technologies or its affiliates in the U.S. and elsewhere (more info here). Other names or brands are trademarks of their respective owners.
  • Anonymous
  • Sign in
  • Create
  • Ask a question
  • Spaces
  • Default
  • Help Room
  • META
  • Moderators
  • Explore
  • Topics
  • Questions
  • Users
  • Badges