In this lecture, we'll look at the EventManager for our Feed the Teddies game. And this EventManager is more flexible and robust but also more complex than the event managers we've seen so far in the course. The first chunk of code we'll look at is the EventName enumeration. So this is just an enumeration that has the names of the five different events that we have in this particular game. We have an event for when the game starts. We have an event for when the game is over. We have an event for when the health changes, when points are added, and when the timer is changed. This next class is a little more interesting. This class is called the IntEventInvoker because it is a class that invokes one or more Int events. The Dictionary here is a new collection class that we haven't looked at before, but I will tell you that dictionaries have a key. In this case, we're using EventName and a value. In this case, it's a UnityEvent that has one int argument, and we can look up values by using keys. And that should remind you of PlayerPrefs where we looked up values using keys. The difference here is that in C#, our key doesn't have to be a string. It can be any data type we want and the value doesn't have to be string, int, or float. It can be any data type we want. So here we're using keys of that enumeration I just showed you, and the values are actual event objects. Now, you should go do an in-video quiz about dictionaries. The reason we have a Dictionary here is because we will end up before we're all done with classes that actually invoke more than one event. And so, we couldn't just have a field for the UnityEvent int. We needed to have a dictionary of unityEvents so that classes can invoke multiple integer events. We also have an AddListener method where the eventName and the listener to listen to that event are passed in as parameters. And notice, of course, this is UnityAction with one int argument because that's the appropriate delegate for listening to a UnityEvent with one int argument. So we pass those two pieces of information in as parameters. And we check with the ContainsKey method to see if that particular eventName is supported by this particular invoker. So ContainsKey checks for that key. And if the Dictionary does contain that key, we know we have a UnityEvent with one int argument for that particular event name. So we do our standard add that listener to the invoker where we get the invoker by putting the key in between square brackets. So this is much like indexing into an array, but this time we're using a key to find something in the Dictionary. The EventManager is the most complicated part although those other two pieces are things we need for our event system in this game. The EventManager has two dictionaries, and the key again is by EventName. The Dictionary of invokers is a list of those IntEventInvokers, because we might have multiple invokers for a particular event. And so, we have a list here instead of just a single invoker. Similarly, the listeners is a dictionary of a list of listeners where each one is a UnityAction with the one int argument delegate. And that's also keyed by the EventName. So, the EventName gives us a way to map between invokers and listeners as we're adding invokers and adding listeners through the EventManager. This Initialize method actually goes through and make sure that the Dictionary has empty lists for every possible EventName. So this part up here might look a little unusual to you. Basically, what it's doing is it's going through each of those five values in the EventName enumeration and doing stuff with that name inside the loop. And so, if the dictionary doesn't have that name already, it creates new lists for the invokers and listeners. And if it already does have that name, it just clears the list. We do it this way because this Initialized method might be called multiple times as we play the game. And we don't want to try to add a new list if the Dictionary already does contain a particular name, because that throws an exception when we try to add something with the same key as the dictionary already has. Adding an invoker looks very similar to what you've seen in the past, although this time we were passing in an eventName in addition to the invoker, and notice there's that IntEventInvoker type. And then we add all the listeners we have for that eventName to this invoker, and then we add the invoker to the list of invokers in the Dictionary for that eventName. Adding a listener is similar. And finally, we actually have something new in this EventManager where we remove an invoker by passing in the eventName and the invoker. And we go to the Dictionary and we remove that particular invoker. And this is an efficiency thing. As the game runs, we have invokers that are destroyed. And we might as well take them out of the Dictionary as they're getting destroyed rather than keeping them hanging around. Those are the core ideas behind the event system in the Feed the Teddies game. To recap, we explored how to implement a pretty robust EventManager. We also saw how we can use C# dictionaries in an EventManager though of course you'll use dictionaries in other places in your game development as well. I said in the lesson introduction that this is one step away from commercial quality EventManager. And the one step is to have an EventManager that supports various types for the invokers and the listeners. And once you take that step, you've got an EventManager you can use in a commercial game, and that's exactly what I'm doing in my balloons extreme game.