• 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 Banemus1 · Jul 31, 2014 at 10:51 AM · messages

How does unity send its messages all over the place?

For example, if you use network. All the gameobjects components will have the functions OnPlayerConnected, OnPlayerDisconnected, etc called on them.

I would like to know how, because I would like to send messages myself all over the place.

Atm I am using a root gameobject called "Game" and I do broadcastmessage on that one. Many people say that using broadcastmessage/sendmessage is really slow. ( I understand why it is slow ). So I was wondering what unity does internally to have this effect?

Comment

People who like this

0 Show 1
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 meat5000 ♦ · Jul 31, 2014 at 10:59 AM 0
Share

It's slow to use repeatedly but is actually a lot faster to use than GetComponent if you need to reach many Objects.

1 Reply

· Add your reply
  • Sort: 
avatar image
Best Answer

Answer by vexe · Jul 31, 2014 at 11:50 AM

@Lucas says they used reflection. See his answer's here. and comments at the end of this blog.

If you're not using SendMessage rapidly in performance-sensitive areas, it's OK.

I don't use it not because it's slow, but because it makes my codes and designs ugly (string literals are a no-no for me...)

If you want a better approach sending messages, consider using delegates. If you want to globally send events, consider using some sort of an event manager, here's what I used in my uFAction

 using System;
 using System.Linq;
 using System.Reflection;
 //using Fasterflect;
 
 namespace uFAction
 {
     /// <summary>
     /// A generic event system based on C#'s delegates
     /// Subscribe (add), unsubscribe (remove) and raise (fire) GameEvents
     /// Derive from GameEvent to create your own events
     /// (There's no target differentiation here nor any other constraint, you could target anything)
     /// </summary>
     public static class EventManager
     {
         /// <summary>
         /// Subscribe (add) a handler to the GameEvent specified by the generic argument `T`
         /// </summary>
         /// <typeparam name="T">The type of GameEvent to unsubscribe from</typeparam>
         /// <param name="handler">The handler that wants to unsubscribe (the handler to be removed)</param>
         public static void Subscribe<T>(Action<T> handler) where T : GameEvent
         {
             EventManagerInternal<T>.Subscribe(handler);
         }
 
         /// <summary>
         /// Unubscribe (remove) a handler to the GameEvent specified by the generic argument `T`
         /// </summary>
         /// <typeparam name="T">The type of GameEvent to subscribe to</typeparam>
         /// <param name="handler">The handler to subscribe (the handler to be added)</param>
         public static void Unsubscribe<T>(Action<T> handler) where T : GameEvent
         {
             EventManagerInternal<T>.Unsubscribe(handler);
         }
 
         /// <summary>
         /// Raises the specified event - Resolves the event type at runtime (uses faster flect cached reflection)
         /// </summary>
         public static void DynamicRaise(GameEvent e)
         {
             var type = typeof(EventManagerInternal<>);
             var eventType = e.GetType();
             var genType = type.MakeGenericType(eventType);
             var raise = genType.GetMethod("Raise", BindingFlags.Public | BindingFlags.Static);
             raise.Invoke(null, new object[] { e });
 
             // if you have Fasterflect, you could call the method like this for better performance
             //var raise = genType.DelegateForCallMethod("Raise", Flags.StaticPublic, eventType);
             //raise(null, e);
         }
 
         /// <summary>
         /// Raise (fire) the GameEvent specified by the generic argument `T`
         /// </summary>
         /// <typeparam name="T">The type of GameEvent to be raised</typeparam>
         public static void Raise<T>(T e) where T : GameEvent
         {
             EventManagerInternal<T>.Raise(e);
         }
 
         /// <summary>
         /// Clears the GameEvent delegate
         /// </summary>
         public static void Clear<T>() where T : GameEvent
         {
             EventManagerInternal<T>.Clear();
         }
 
         /// <summary>
         /// Returns true if the specified handler is contained in the GameEvent's delegate invocation list
         /// </summary>
         public static bool Contains<T>(Action<T> handler) where T : GameEvent
         {
             return EventManagerInternal<T>.Contains(handler);
         }
 
         /// <summary>
         /// Rasies the game event 'e' to all handlers except the ones specified
         /// </summary>
         public static void RaiseToAllExcept<T>(T e, params Action<T>[] handlers) where T : GameEvent
         {
             EventManagerInternal<T>.RaiseToAllExcept(e, handlers);
         }
 
         /// <summary>
         /// Raises the game event 'e' only to the specified handlers
         /// </summary>
         public static void RaiseToOnly<T>(T e, params Action<T>[] handlers) where T : GameEvent
         {
             EventManagerInternal<T>.RaiseToOnly(e, handlers);
         }
 
         /// <summary>
         /// The internal event manager class - do not be afraid, doing a:
         /// EventManagerInternal`Event1`.Sub(...); and EventManagerInternal`Event2`.Sub(...);
         /// the compiler will _not_ create two seperate classes - they will use the same place in memory!
         /// If you don't know what I'm talking about, see Jamie King's: https://www.youtube.com/watch?v=9eZnUk0Gu7M 
         /// </summary>
         private static class EventManagerInternal<T> where T : GameEvent
         {
             private static Action<T> action;
 
             public static void Subscribe(Action<T> handler)
             {
                 action += handler;
             }
 
             public static void Unsubscribe(Action<T> handler)
             {
                 action -= handler;
             }
 
             public static void Raise(T e)
             {
                 if (action != null)
                     action(e);
             }
 
             public static void RaiseToAllExcept(T e, params Action<T>[] handlers)
             {
                 var toInvoke = from d in action.GetInvocationList()
                                where !handlers.Contains(d)
                                select (Action<T>)d;
 
                 foreach (var handler in toInvoke)
                     handler(e);
             }
 
             public static void RaiseToOnly(T e, params Action<T>[] handlers)
             {
                 foreach (var h in handlers)
                     h(e);
             }
 
             public static void Clear()
             {
                 action = null;
             }
 
             public static bool Contains(Action<T> handler)
             {
                 if (action == null)
                     return false;
 
                 return action.GetInvocationList().Any(d => d.Equals(handler));
             }
         }
     }
 }
 
 namespace uFAction
 {
     /// <summary>
     /// An abstract base class for creating events - derive from it to create your own game events to use
     /// in the generic event system, EventManager.
     /// </summary>
     public abstract class GameEvent
     {
     }
 }

See the doc in the link ^ for usage examples.

You basically create an event:

 public class OnPlayerDied : GameEvent
 {
    public GameObject Player { get; set; }
    public MoreInfo info { get; set; }
 }

Listen to that event:

 public class GameManager : MonoBehaviour
 {
    void OnEnable() { EventManager.Subscribe<OnPlayerDied>(DeathHandler); }
    void OnEnable() { EventManager.Unsubscribe<OnPlayerDied>(DeathHandler); }
    void DeathHandler(OnPlayerDied arg)
    {
       print("Player + " arg.Player.name + " has died");
    }
 }

And raise the event somewhere:

 public class Player : MonoBehaviour
 {
    private int health;
    public int Health
    {
       get { return health; }
       set { 
           health = value; 
           if (health <= 0) 
              EventManager.Raise(new OnPlayerDied { Player = gameObject, MoreInfo = new MoreInfo(...) });
        }
 }


Comment
clunk47

People who like this

1 Show 0 · 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

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

4 People are following this question.

avatar image avatar image avatar image avatar image

Related Questions

how to make out like little notes? 2 Answers

Get isServer from NetworkMessage 0 Answers

Multiple Choice question to popup when pressing a key 0 Answers

Get List of Signatures of Messages to Monobehaviour 1 Answer

Messages in Multiplayer 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