Wayback Machinekoobas.hobune.stream
May JUN Jul
Previous capture 12 Next capture
2021 2022 2023
1 capture
12 Jun 22 - 12 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 /
  • Help Room /
avatar image
0
Question by Kossuranta · Oct 20, 2016 at 12:19 PM · optimizationstaticbest practices

Find() vs static variable that constains GameObject vs static method that returns GameObject

This probably is one of the quetions in the series of "It really doesn't matter / use what you prefer", but is there any difference which way I get GameObject that isn't already in scene (can't be dragged to Inspector).

Simplified situation: I have 2 scenes and GameObject called Data is created on first scene and is set as "DontDestroyOnLoad". I need to access script in this Data GameObject at seconds scene, but I need to get it first somehow.


Solution 1:

Simply use Find() to get it.

 //Some other script in some other object
 public GameObject data;
 
 void Awake()
 {
     data = GameObject.Find("Data");
 }



Solution 2:

In script that is attached to Data GameObject create static variable that contains itself.

 //Data.cs
 static public GameObject thisObj;
 
 void Awake()
 {
     data = gameObject;
 }
 
 //In some other script in some other object
 public GameObject data;
 
 void Awake()
 {
     data = Data.thisObj;
 }



Solution 3:

In script that is attached to Data GameObject create static method that returns itself;

 //Data.cs
 static public GameObject GetGameObject()
 {
     return gameObject;
 }
 
 //In some other script in some other object
 public GameObject data;
 
 void Awake()
 {
     data = Data.GetGameObject();
 }



Which of these would you use and why or is there some better way to do this? I have mostly used the first solution, but technically solutions 2 and 3 might be somewhat better as Find() is kinda slow. I have been trying to avoid using static if there is some other solution as have had some strange issues with excessive static usage.

Comment
Add comment
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

2 Replies

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

Answer by Bonfire-Boy · Oct 20, 2016 at 12:33 PM

Following tradition, I will award the prizes in reverse order...

"Solution" 3.

Have you tried this? It won't compile because Data.gameObject (inherited from MonoBehaviour, presumably) is not static and therefore not accessible from your static function.

Solution 2.

This code is dangerous. It is essentially a highly-simplified version of a design pattern called "Singleton", which is a way of achieving what you're after. But you should research Singletons before trying to use one; you will find that they are dangerous if not implemented carefully. This is partly due to their use of statics - you are correct to conclude from your experience that statics should be used sparingly.

Solution 1.

Find-ing may not be recommended if it needs to be performed regularly. But doing it once, when your scene loads, is not a big deal.

I would go with this one for now as it is quick and easy and not too dangerous so long as you only create the one object with that name.

Note that you could also choose to Find it by Component-type or by Tag. The former would be the most robust way of doing things if you only have one of them, whereas using names and/or tags would allow you to have multiple instances.

You might also consider looking into the proper way to implement a Singleton MonoBehaviour class (you'll find examples by searching). But like I said, be careful. If you do it wrong (as you have), it might appear to work only to create severe problems later on.

Comment
Add comment · Show 1 · 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 Kossuranta · Oct 20, 2016 at 02:11 PM 0
Share

No I haven't tried third one, just came to my $$anonymous$$d while writing first two, but obviously didn't think it through. Will keep using Find/FindWithTag, but gotta start learning about Singleton, probably good to at least know what it is :)

Thanks!

avatar image
0

Answer by Owen-Reynolds · Oct 20, 2016 at 02:09 PM

In practice, I've found it easiest to use a single global static pointer to the script, sort of like your item 2:

 class commonStuffA : MonoB {
   public static commonStuffA ptr;
   void Awake() { ptr=this; }

   public Texture2D T1; // set in Inspector
   public void usefulFunc() {}
 }

And then anyone can use it, nothing extra needed, with commonStuffA.ptr.usefulFunc();.

Comment
Add comment · Show 1 · 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 Bonfire-Boy · Oct 20, 2016 at 02:19 PM 0
Share

I know this can work ok if you're careful and know what you're doing but like I said in my answer, this kind of "$$anonymous$$imal Singleton" scares me.

I would suggest, at the very least, additions along these lines...

 class commonStuffA : $$anonymous$$onoB 
 {
    public static commonStuffA ptr = null;
    void Awake() 
    {
         if (ptr != null) 
         { 
              Debug.LogError("Creating a second commonStuffA");
         }
         else
         { 
             ptr=this;
         } 
    }
    void OnDestroy()
    {
         if (ptr == this) ptr = null;
    }
 // etc
 }

@$$anonymous$$ossuranta The above might give you an idea of the kind of dangers the technique can introduce. In fully-fledged Singleton classes you'll find "trap-spotters" along those lines, along with others.

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

61 People are following this question.

avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image

Related Questions

Static batching break : objects belong to different static batches 0 Answers

Static Collider.Move warning is still in place: should I add Rigidbody or not? (Unity 5.3.3f1) 0 Answers

More saved batches than actual number of batches? 1 Answer

Removing Tris/Verts/Polygons from an merged mesh? (C#) 0 Answers

reuse texture between quad 0 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