• 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
1
Question by yehielc · Sep 17, 2019 at 11:33 AM · findobjectoftype

Multiple FindObjectOfType to the same object, best practice

Hi, I am referencing a central script from another script multiple times, something like this:

     FindObjectOfType<GameSession>().activeEngine = 0;
     FindObjectOfType<GameSession>().mainGun = 0;
     FindObjectOfType<GameSession>().activeGun = 0;

I was wondering if there's a more efficient way ?

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

1 Reply

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

Answer by Bunny83 · Sep 17, 2019 at 12:02 PM

Just cache the reference once and then reuse it.

 GameSession gs = FingObjectOfType<GameSession>();
 gs.activeEngine = 0;
 gs.mainGun = 0;
 gs.activeGun = 0;

Of course if you have to reference this script from multiple places and there is always only one instance it's better to implement a MonoBehaviour based singleton. Inside your GameSession class:

 public GameSession : MonoBehaviour
 {
     private static GameSession m_Instance = null;
     public static GameSession Instance
     {
         get
         {
             if (m_Instance == null)
             {
                 m_Instance = FingObjectOfType<GameSession>();
                 m_Instance.transform.parent = null;
                 DontDestroyOnLoad(m_Instance.gameObject);
             }
             return m_Instance;
         }
     }
     // the rest of your script
 }


Now you can simply use

 GameSession.Instance.activeEngine = 0;
 GameSession.Instance.mainGun = 0;
 GameSession.Instance.activeGun = 0;

from any other script. It will automaticalls call FindObjectOfType the first time you use the Instance property. From that point on it will only return the already cached reference.


Note the lines

 m_Instance.transform.parent = null;
 DontDestroyOnLoad(m_Instance.gameObject);

just ensure that the object will stay alive when you change the scene. However if you have an instance of your GameSession in each scene this would cause issues when you load a new scene. If you want the GameSession to be destroyed at a scene change, just remove those two lines.

Comment
Add comment · Show 4 · 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 yehielc · Sep 18, 2019 at 07:24 PM 0
Share

This makes the code much cleaner! thanks! i was using a different singleton script for my "GameSession" but without the static variables, dont i need to place the singleton inside an OnAwake() function or something like that?

also 1 small thing, if i destory the GameSession at the end of the game, and instantiate a new one just at the start of the game, can i still use the singleton with the static variables?

avatar image Bunny83 yehielc · Sep 19, 2019 at 01:58 AM 1
Share

Yes, you can use this singleton pattern since the null check will detect destroyed objects thanks to Unity's custom == operator. However destroying and recreating a singleton can cause issues depending on the order of your code. If the singleton is destroyed and some code tries to access the singleton which has not yet been recreated will of course cause problems. If the class doesn't need any serialized values you could even create a second stage when the FingObjectOfType fails it would automatically create an instance. This doesn't always make sense for all kinds of singletons. Though if your class allows this you can do this ins$$anonymous$$d:

      get
      {
          if (m_Instance == null)
          {
              m_Instance = FingObjectOfType<GameSession>();
              if (m_Instance == null)
                  m_Instance = (new GameObject("GameSession")).AddComponent<GameSession>();
              m_Instance.transform.parent = null;
              DontDestroyOnLoad(m_Instance.gameObject);
          }
          return m_Instance;
      }

This will first check if we have a cached instance that is still alive. If not it will search for one using FingObjectOfType. If no instance is found it will simply create a new gameobject with that script attached.


Note that if your class doesn't need any Unity callbacks it probably shouldn't be a $$anonymous$$onoBehaviour in the first place. $$anonymous$$onoBehaviours have quite a bit more overhead compared to a normal C# class. Though we don't know enough about your class to suggest any particular version.

avatar image yehielc Bunny83 · Sep 19, 2019 at 06:50 AM 0
Share

Thanks for the explanation! I'm Quite of a noob programmer so i use $$anonymous$$onoBehaviour for everything since i thought every reference to gameObjects needs to be in $$anonymous$$onoBehaviour... what is a unity callback and what isn't is a huge topic on it on :))

avatar image ALIENPANDA · Jul 23, 2021 at 05:44 PM 0
Share

So which one will be a good practice

 void start()
 {
 GameSession gs = FingObjectOfType<GameSession>();
  gs.activeEngine = 0;
  gs.mainGun = 0;
  gs.activeGun = 0;
 }

or

     public static GameSession instance;
     private void Awake()
     {
         instance = this;
     }
     something = GameSession.instance.objectreference; // this reference in other script




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.

Welcome to Unity Answers

If you’re new to Unity Answers, please check our User Guide to help you navigate through our website and refer to our FAQ for more information.

Before posting, make sure to check out our Knowledge Base for commonly asked Unity questions.

Check our Moderator Guidelines if you’re a new moderator and want to work together in an effort to improve Unity Answers and support our users.

Follow this Question

Answers Answers and Comments

112 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 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

Alternatives to GameObject.Find() and GameObject.FindObjectsOfType() to also get disabled objects/components 1 Answer

FindObjectOfType returns destroyed object (leading to MissingReferenceException) 0 Answers

FindObjectOfType vs. GetComponent 0 Answers

More Efficient Way to Find Active GameObject 2 Answers

FindObjectOfType or FindWithTag 1 Answer


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