• 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
Question by ProgrammerAdam · Oct 02, 2014 at 10:37 AM · c#networkinginterfacedelegate

Implementing Unity's Callback System

Hi all, I'm working on a Networking Library for Unity, I need to implement callbacks, or "messages" as the Unity doc calls them, such as OnConnectedToServer(), OnPlayerConnected(), etc, but I don't know how to go about doing it. I've used delegates and interfaces before, but I can't figure out how they work to create these callbacks that are built into MonoBehaviour. If anyone can provide insight or further reading it would be much appreciated. Thanks!!

Comment

People who like this

0 Show 0
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
Best Answer

Answer by Arder Blackard · Oct 02, 2014 at 11:10 AM

You can use the Reflection. The straightforward example can look like following.

     class ConnectionData
     {
         //  Some hypothetical data to be passed to the event with paramater
     }   
 
     class Manager
     {
         List<System.Object> _listeners  = new List<object>();
 
         public void AddListener( System.Object listener )
         {
             if ( listener != null )
                 _listeners.Add( listener );
         }
 
         public void SendConnectedToServerMessages( ConnectionData data )
         {
             //  Search non-static methods both public and non-public
             BindingFlags flags = BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic;
             //  Parameters of the method to search for
             Type[] paramTypes = { typeof( ConnectionData ) };
 
             //  Parameter value to be passed to the method
             System.Object[] paramValues = { data };
 
 
             foreach ( System.Object obj in _listeners )
             {
                 //  Search for the method with signature OnConnectedToServer( ConnectionData )
                 MethodInfo methodInfo = obj.GetType()
                                            .GetMethod( "OnConnectedToServer", flags, null, paramTypes, null );

                 //  Call the method with parameters
                 if ( methodInfo != null) 
                     methodInfo.Invoke( obj, paramValues );
             }
         }
     }

Manager stores links to the objects that should accept the events in _listeners list, and then upon calling the SendConnectedToServerMessages() searches through all the listeners, and if they have appropriate method - calls them with given parameters (if the listener has no such a method - not$$anonymous$$ng will be done). Of course it is just a sample, more optimization would be nice to have (like precac$$anonymous$$ng the MethodInfo structures) but t$$anonymous$$s is the point to start from.

http://msdn.microsoft.com/en-us/library/ms173183.aspx - t$$anonymous$$s is the starting page for the Reflection topics on MSDN

Comment

People who like this

0 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 ProgrammerAdam · Oct 02, 2014 at 12:35 PM 0
Share

Thank you! Don't know that I ever would have stumbled upon reflection based on how I was searching.

So, if I'm understanding your code correctly, I'd call AddListener from every script that had a ConnectedToServer method in order to register it with the manager?

avatar image Arder Blackard · Oct 02, 2014 at 02:32 PM 0
Share

With this approach you can have in the manager a number of methods like SendConnectedToServerMessages(), SendPlayerConnectedMessages() and so on (lets call them event-emitting methods). Then objects which want to process all or some of these events (listeners) should implement the appropriate methods and register themselves within the Manager by calling AddListener() (some unregister or cleanup routine to remove the destroyed objects may be needed too). When implemented like this, the listeners are not required to be the child of some common class, implement any interface - they just need to have some methods with correct signatures declared (much like Update(), Start(), OnEnable()... in MonoBehaviour). Then upon emitting the certain event for each listener if it has an expected method - it will be called, if not - the object will not receive the message (again like the MonoBehaviour descendants). I'm pretty sure that Unity maintains some kind of global list of all MonoBehaviours which acts like the proposed Manager.

BTW Reflection can give you in runtime the detailed information about any type, class, variable, method and so on (even those that are private and are not accessible otherwise) alowing to explore unknown objects, call their methods, change fields values - sometimes it may be handy (of course there can be some performance drawback for this but using it wisely can help a lot).

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

3 People are following this question.

avatar image avatar image avatar image

Related Questions

C# inheritance advice 2 Answers

Multiple Cars not working 1 Answer

Distribute terrain in zones 3 Answers

UNET Server not setting [SyncVar] 0 Answers

Networking Sync SetActive Not Working 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