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 /
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.

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

FindObjectOfType won't find object that hasn't had "Awake" called? 1 Answer

How do I get gameobjects to fire a method based on an interface? 1 Answer

dontdestroyonload breaks findobjectoftype 0 Answers

Calling a function of another object's child? 1 Answer

Null Reference after finding object already 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