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 MrVerdoux · Nov 26, 2013 at 09:46 AM · c#unity input

Lazy initialization of a MonoBehaviour derived class without singleton

I have made myself an gesuture recognition class with C# (similar to Input). The thing is, it is a children of MonoBehaviour (so it cannot be made static) because it needs Update, but I want it to be lazy initialized, so I don´t ever forget to include it in my projects.

I know I could use a singleton to solve this, but I don´t want to write GestureRecognition.Instance every time I need to check something, I want it to be clean and similar to Unity´s Input. Is this possible?

Thanks.

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

3 Replies

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

Answer by GameVortex · Nov 26, 2013 at 12:42 PM

I had an idea. Maybe instead of having the GestureRecognition as child of MonoBehaviour, you put it as a static class and then have a GestureRecognitionUpdater class that controls the update of the GestureRecognition class.

Example:

 public class GestureRecognitionUpdater : MonoBehaviour
 {
     private void Awake()
     {
         DontDestroyOnLoad(gameObject);
     }
 
     private void Update()
     {
         GestureRecognition.Update();
     }
 }

And then in the GestureRecognition you could do something like this:

 public class GestureRecognition
 {
     private static bool initialized;
 
     public static void Initialize()
     {
         if (!initialized)
         {
             new GameObject("GestureRecognitionUpdate").AddComponent<GestureRecognitionUpdater>();
             initialized = true;
         }
     }
 
     public static void Update()
     {
         //Do the update stuff
     }
 
     public static void GetGesture()
     {
         Initialize();
 
         //Do the get gesture stuff
     }
 }

This way you get the static access to all the functions of GestureRecognition class and it also gets Updated each frame and you won't have to double up on writing wrappers for each function.

You would have to either call the Initialize function on all the other functions to check for if the Updater has been initialized, or you have to call the Initialize function on the start of your game.

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
avatar image
3

Answer by Bunny83 · Nov 26, 2013 at 12:17 PM

No need for a second class. You can hide the singleton inside the class itself:

 public class GestureRecognition : MonoBehaviour
 {
     private static GestureRecognition m_Instance = null;
     private static GestureRecognition Instance
     {
         get
         {
             if (m_Instance == null)
             {
                 m_Instance = (GestureRecognition) FindObjectOfType(typeof(GestureRecognition ));
                 if (m_Instance == null)
                 {
                     m_Instance = (new GamaObject("GestureRecognition")).AddComponent<GestureRecognition>();
                 }
                 DontDestroyOnLoad(m_Instance.gameObject);
             }
             return m_Instance;
         }
     }
     
     public static void RecognizeGesture()
     {
         Instance._RecognizeGesture();
     }
     private void _RecognizeGesture()
     {
         // do something on the instance
     }
     private void Update()
     {
         // ...
     }
 }

whenever you access one of the static methods of your class it automatically creates an instance. You can't even access Instance from outside since it's only used in other static methods.

That said, to answer the question, it's generally bad design to implement such things the lazy way. That way your class is tightly bound to other classes. For example: If you create your class using Input.touches. You add more and more stuff and everything's working fine. Now you want it to work on PC and web as well... No way without rewriting the whole thing with mouse input.

There are so many great software design patterns out there, but most people pick the worst one (the singleton pattern).

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 MrVerdoux · Nov 26, 2013 at 01:00 PM 0
Share

Thank you, specially for the softare design lesson, I find it insteresting and I think I will make some research on what is the best way to hande this.

avatar image Tomer-Barkan · Nov 26, 2013 at 01:33 PM 1
Share

These are all variations of the singleton design pattern. The best way is what works best for you. I personally use the typical singleton implementation where I use .Instance to access it. It's not that much extra typing with all the code-complete functionality these days, and it helps you remember that you're using a singleton (+ will make your code more "mainstream", which means other people will have an easier time reading it, helping you, etc).

avatar image
2

Answer by Tomer-Barkan · Nov 26, 2013 at 09:56 AM

If it's that important to you not to use the .Instance part, you could create a static class that will have its own instance and expose all the functionality that your GestureRecognition class has:

 // this is a new class, not the one you created
 public class GestureRecognition {
     public static GestureRecognitionInternal instance;
 
     public static void RecognizeGesture() {
         instance.RecognizeGesture();
     }
 }
 
 // this is your original class
 public class GestureRecognitionInternal : MonoBehaviour {
     public void Awake() {
         GestureRecognition.instance = this;
     }
 
     public void RecognizeGesture() {
         // your code here
     }
 }
Comment
Add comment · Show 5 · 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 ArkaneX · Nov 26, 2013 at 10:09 AM 1
Share

Depending on the game, it might be a good idea to add DontDestroyOnLoad to Awake. Othwerwise, if the game loads another level, you might end up with NullReferenceException.

avatar image MrVerdoux · Nov 26, 2013 at 11:14 AM 0
Share

But then I would need to call GestureRecognition.instance, which is the same as before!

avatar image Tomer-Barkan · Nov 26, 2013 at 11:54 AM 0
Share

No, if you create a static function for each function in your gesture recognition class, such as RecognizeGesture() in my example, then you simply call GestureRecognition.RecognizeGesture()...

avatar image ArkaneX · Nov 26, 2013 at 12:00 PM 0
Share

The idea behind tbkn answer is that you duplicate methods from GestureRecognitionInternal class in GestureRecognition class (btw - this class might be static). If you want to call a method, for example RecognizeGesture(), you just do

 GestureRecognition.RecognizeGesture()

which in turn calls exactly the same method on the stored GestureRecognitionInternal instance.

To prevent confusion, you can make instance field private, and introduce method SetInstance, which you could call in Awake.

 public static void SetInstance(GestureRecognitionInternal instance)
 {
     this.instance = instance;
 }
avatar image MrVerdoux · Nov 26, 2013 at 12:59 PM 0
Share

Ok now I understand it, thank you! I still would have the same issue for variables however, although I could solve it with properties... Probably I should bear the ".Instance" because this seems kind of tedious in the long term.

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

20 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

Related Questions

Multiple Cars not working 1 Answer

Distribute terrain in zones 3 Answers

Jumping by using unity input system 1 Answer

New Unity Input System Delay on Keyboard 0 Answers

Flip over an object (smooth transition) 3 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