Using C# Events with Unity

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:

// This script triggers the event:
if(GUI.Button (...))
    {
    // trigger event
    }

In another object we have:

// This script also triggers the same event:
if(Raycast (...))
    {
    // trigger event
    }

In another object we have:
// This function gets triggered by the event:

void TriggerEvent()
    {
    // does stuff
    }

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!

Here’s a couple of c# event tutorials. You’re going to want to understand what’s happening if you’re going to use c# events or you’re bound to have problems.

http://msdn.microsoft.com/en-us/library/aa645739(VS.71).aspx

Using System is for C# functionality. Let it be.

As for your problem I suggest :

http://www.levelbylevel.com/blog/unity-c-messenger-tutorial/
(The second link is a tutorial for the messenger)

Pretty simple to use and pretty handy.

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!!!

:smile:

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:

// Player.cs
namespace PlayerStuff
{
   public delegate void PlayerRespawnedEventHandler(float x, float y);
   
   class Player
   {
       public event PlayerRespawnedEventHandler PlayerHasRespawned;
       private Vec2 m_pos;

       public Player(Vec2 pos)
       {
           // Initialise player
           m_pos = pos;
       }

       // Lots of player stuff

       private PlayerDied()
       {
           // Respawn player

           // null check not necessary, but helps
           if(PlayerHasRespawned != null)
           {
              // All listeners will be invoked
              PlayerHasRespawned(m_pos.x, m_pos.y);
           }
       }
   }
}

Then some other file

// GameEvents.cs

namespace GameStuff
{
    class Status
    {
        // Doing stuff
        
        public Status()
        {
           // Get handle to player game object
           
           // Now hook up to event 
           playerGameObject.PlayerHasRespawned += new PlayerRespawnedEventHandler(ActOnRespawn);
        }

        private void ActOnRespawn(float x, float y)
        {
            // Do the funky chicken.
        }
    }
]

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:

namespace GenericEvents
{   
   class EventTriggerer
   {
       public event EventHandler OurEvent;

       public void TriggerEvent()
       {
          if(OurEvent != null)
          {
             OurEvent();
          }
       }
   }

   class OtherObject
   {
         private EventTriggerer m_trig;
         public SomeFunction()
         {
              if(GUI.Button)
              {
                   m_trig.TriggerEvent();
              }
         }
   }
}

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.

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: http://wiki.unity3d.com/index.php?title=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:
http://forum.unity3d.com/threads/112449-Advanced-C-Messenger/page2

Hope it benefits anyone :wink:

just use c# delegates and events.

you can create events by doing this

public delegate void EventHandler();
public static event EventHandler onGameActive;
public static event EventHandler onResetAll;

than to trigger them

if (onGameActive != null)
    onGameActive();

and finally subscribe by doing this in your monobehaviors Start or Awake Method

Game_System_Logic.onResetAll += this.ResetAll;

pretty easy and elegant

1 Like

I’ve created video showing you where and how to use Events, according to good MVC practices

The is malware/phishing in that link. Please delete or moderators sort out. Thanks

1 Like