Search Unity

  1. We've closed the job boards. If you're looking for work, or looking to hire check out Unity Connect. You can see more information here.
    Dismiss Notice
  2. We're running great holiday deals on subscriptions, swag and Asset Store packages! Take a peek at this blog for more information!
    Dismiss Notice
  3. Check out our Unite Austin 2017 YouTube playlist to catch up on what you missed. More videos coming soon.
    Dismiss Notice
  4. Unity 2017.2 is now released.
    Dismiss Notice
  5. The Unity Gear Store is here to help you look great at your next meetup, user group or conference. With all new Unity apparel, stickers and more!
    Dismiss Notice
  6. Introducing the Unity Essentials Packs! Find out more.
    Dismiss Notice
  7. Want to see the most recent patch releases? Take a peek at the patch release page.
    Dismiss Notice
  8. Unity 2017.3 beta is now available for download.
    Dismiss Notice

Using C# Events with Unity

Discussion in 'Scripting' started by Vimalakirti, Aug 24, 2010.

  1. Vimalakirti


    Oct 12, 2009
    I am having a hard time figuring out how to use C# events with my Unity scripts. I'm not that experienced.

    What I would like is to be able to trigger an event when I want and have various scripts in various objects receive the message that the event has been triggered to do stuff of their own.

    Could someone post a generic event handler in C# that I can use as a template for my own code please? I'm looking for something like this:

    In one object we have:
    Code (csharp):
    1. // This script triggers the event:
    2. if(GUI.Button (...))
    3.     {
    4.     // trigger event
    5.     }
    In another object we have:
    Code (csharp):
    1. // This script also triggers the same event:
    2. if(Raycast (...))
    3.     {
    4.     // trigger event
    5.     }
    In another object we have:
    // This function gets triggered by the event:
    Code (csharp):
    1. void TriggerEvent()
    2.     {
    3.     // does stuff
    4.     }
    And yet other objects can also be triggered and do their own thing.

    I'm wading through Daniel Solis' book Illustrated C# 2005 which has enabled me to translate my scripts from JS to C#, but for some reason I'm choking on Events.

    Also, do I have to use another "using System." statement?

    Thank you!
  2. Eagle32


    Jun 20, 2010
  3. jedy


    Aug 1, 2010
  4. Vimalakirti


    Oct 12, 2009
    After further struggles I used jedybg's out of the box solution, or rather it's predecessor, CSharpMessenger, from the Wiki here:

    It's just too easy not to use! Perhaps someday when I have more than a week of c# experience under my belt I'll be able to write and use Delegates and Events on my own as needed, but until then this solution will free my time to continue to learn about the basics of object oriented programming.

    Thanks for those links to both of you!!!

  5. DifficultMass


    Feb 10, 2010
    I don't know whether it's different within Unity (just come back after a long time away and still only exploring this wonderful software.)

    However, events, C# style:

    Code (csharp):
    3. // Player.cs
    4. namespace PlayerStuff
    5. {
    6.    public delegate void PlayerRespawnedEventHandler(float x, float y);
    8.    class Player
    9.    {
    10.        public event PlayerRespawnedEventHandler PlayerHasRespawned;
    11.        private Vec2 m_pos;
    13.        public Player(Vec2 pos)
    14.        {
    15.            // Initialise player
    16.            m_pos = pos;
    17.        }
    19.        // Lots of player stuff
    21.        private PlayerDied()
    22.        {
    23.            // Respawn player
    25.            // null check not necessary, but helps
    26.            if(PlayerHasRespawned != null)
    27.            {
    28.               // All listeners will be invoked
    29.               PlayerHasRespawned(m_pos.x, m_pos.y);
    30.            }
    31.        }
    32.    }
    33. }
    Then some other file

    Code (csharp):
    2. // GameEvents.cs
    4. namespace GameStuff
    5. {
    6.     class Status
    7.     {
    8.         // Doing stuff
    10.         public Status()
    11.         {
    12.            // Get handle to player game object
    14.            // Now hook up to event
    15.            playerGameObject.PlayerHasRespawned += new PlayerRespawnedEventHandler(ActOnRespawn);
    16.         }
    18.         private void ActOnRespawn(float x, float y)
    19.         {
    20.             // Do the funky chicken.
    21.         }
    22.     }
    23. ]

    The event that Player exposes is of type PlayerRespawnedEvenHandler. This defines the data that will be supplied when the event is called. Our GameStff class wants to know when a player has respawned and so after getting a handle to the instance (will be via a Unity API call, I guess) can hook up to the event. It is effectively saying when the event happens, I'll (GameStuff) do some actions that you (Player) don't need to know about. You could also say Player has delegated some work away from itself, but given the paradigm, it's verging on chicken/egg debate. Anywho, the GameStuff tells the event that when it is invoked, it should call the function ActOnRespawn, which as we can see, has the necessary parameters in the function definition.

    So, when the player dies, we'll assume PlayerDied gets called to respawn the player. Within this, it checks to see if anyone cares about the event (not a necessary check, but a good safety) and will invoke the event if necessary. You can think of this as calling a function, as that is pretty much what it is, it just doesn't know if/where these functions are in memory until they are hooked up at runtime.

    In your case, you could simply define the event as an EventHandler, which takes no arguments (and means no need for declaring the delegate) so Player.cs would be:

    Code (csharp):
    2. namespace GenericEvents
    3. {  
    4.    class EventTriggerer
    5.    {
    6.        public event EventHandler OurEvent;
    8.        public void TriggerEvent()
    9.        {
    10.           if(OurEvent != null)
    11.           {
    12.              OurEvent();
    13.           }
    14.        }
    15.    }
    17.    class OtherObject
    18.    {
    19.          private EventTriggerer m_trig;
    20.          public SomeFunction()
    21.          {
    22.               if(GUI.Button)
    23.               {
    24.                    m_trig.TriggerEvent();
    25.               }
    26.          }
    27.    }
    28. }

    Every object that was going to trigger the event would need a handle to the object that contained the event to be triggered, but it would enable that event to be triggered by any other given object at any time and so anything that was in turn subscribed to the event OurEvent would be invoked accordingly.

    Hopefully that makes sense. It's late and when you use something every day, it sometimes becomes difficult to explain clearly without going into too much, unnecessary detail.
  6. paskal007r


    Sep 6, 2013
    I've come here to find out about defining my events in c#, a matter in which I was completely ignorant until last week. This thread was immensely useful, thanks to everyone.

    Digging deeper i also found Advanced CSharp Messenger:
    An updated version of the messenger linked in the above posts.

    Also, here is the link to a discussion where the messenger has been recently updated:

    Hope it benefits anyone ;)
    Last edited: Feb 6, 2014
  7. cmcpasserby


    Jul 18, 2014
    just use c# delegates and events.

    you can create events by doing this
    Code (CSharp):
    1. public delegate void EventHandler();
    2. public static event EventHandler onGameActive;
    3. public static event EventHandler onResetAll;
    than to trigger them
    Code (CSharp):
    1. if (onGameActive != null)
    2.     onGameActive();
    and finally subscribe by doing this in your monobehaviors Start or Awake Method
    Code (CSharp):
    1. Game_System_Logic.onResetAll += this.ResetAll;
    pretty easy and elegant