Events and Delegates in Unity
How can we use Events and Delegates in Unity and make easy our life?
If you already know how the events and delegates works, you can use the code below as a quick reference, otherwise keep reading.
Delegate and Event
public class SomeClass { public delegate void MethodNameEventHandler(Params sender); public static event MethodNameEventHandler MethodNameEnded = delegate { }; // Doing "= delegate {};" there is no need to do "if (MethodNameEnded != null) MethodNameEnded(sender)" protected virtual void OnMethodNameEnded(Params sender) { // Doing "= delegate {};" in the event above there is no need to do: // if (MethodNameEnded != null) // { // MethodNameEnded(sender); // } MethodNameEnded(sender); } }
Suscribe class
public class SecondClass { void OnEnable() { FirstClass.MethodNameEnded += OnMethodNameEndedSecondClass; } void OnDisable() { FirstClass.MethodNameEnded -= OnMethodNameEndedSecondClass; } public void OnMethodNameEndedSecondClass(Params sender) { // Actions } }
Your first time with Events and delegates? Keep reading
The concept behind this idea is simple, is very annoying having a guy asking all the time for the end of a task, like this one.
By viewing the above video, I’m sure you already know what’s going on with the events, why consume update time asking for an state while we can wait for a notification.
void Update() { if (HistoryManager.journeyEnds) { donkey.askingForTheJourney = false; } }
The next is the Events approach, we have to create a function which is going to notify about some event, in this case, the end of the journey
public class Journey { // Access: public // Keyword: delegate // Return type: void // Method name: JourneyFinishedEventHandler // Params: ((Type)Character (value)character) public delegate void JourneyFinishedEventHandler(Character character); public static event JourneyFinishedEventHandler JourneyFinished = delegate { }; protected virtual void OnJourneyFinished(Character character) { JourneyFinished(charachter); } }
Now we can use the events in the Journey class in the HistoryManager and receive advice over the event JourneyFinished, we mush suscribe to the event in the OnEnable method and Unsuscribe to the event in OnDisable method.
public class HistoryManager { public journeyEnds = false; // Suscribe to the event void OnEnable() { // Class.EventToSuscribe += MyMethodToHandleTheEvent Journey.JourneyFinished += OnJourneyFinished; } // Unsuscribe to the event to avoid memory leaks void OnDisable() { // Class.EventToSuscribe -= MyMethodToHandleTheEvent Journey.JourneyFinished -= OnJourneyFinished; } // Method to handle the event void OnJourneyFinished(Character character) { character.DoSomeAction(); StartNewScene(); } }
Ok, I understand, but why do I have to do all this?
Imagine this situation, at the beginning of the project the annoying designer says: «Ok our game will be awesome if we advice just to the donkey», but you, as a good programmer, you know how the designer mind works, and you know that at the end of the week he is going to ask to advice a second character too, and before the project ends the designer is so stubborn and he wants to advice everybody.
void Update() { if (HistoryManager.journeyEnds) { donkey.askingForTheJourney = false; // second charachter // .... // .... // .... // .... // .... // n character } }
And at the end, you are responsible for this very ugly and unmaintainable code, with the other approach, each time you need to create a new character, you just have to create a new class and suscribe to the event or all the events you want to track, is a good way to keep your code clean and neat.
So, now you know, don’t follow the donkey approach, be patient and wait for the event advice.