In this lecture, we'll refactor our TeddyBear destruction game to use events and an event manager instead of having multiple objects called the add points function in the game HUD. This will decouple our loot actor, teddy bear actor, and Launcher pawn from the game HUD. I've added a couple of classes to our TeddyBear destruction game, I have a delegate declarations class, which is a U object, and I have an event manager actor, which is an actor, and as before, I turned the event manager actor C++ class into a blueprint, added a gameplay tag for event manager tag to the blueprint with that tag, and as you can see, added it to my map here. Let's go take a look at our code. In our delegate declarations, I declared a multicast delegate, and this one I called an F points added event, and it has one parameter, an integer, the number of points that have been added. As I mentioned previously, I can't actually use an event here. I need to use a multicast delegate because I have three different classes that are actually going to broadcast this event. The lute actor, the teddy bear actor, and the Launcher pawn. This is one of those places where using a multicast delegate instead of an event makes a lot of sense. One of the problems that we're faced with is in my Event Manager, we know when we added an event manager and a talker actor was the only invoker that we used the address of the talker actor objects as both the elements in my TRA of invokers and as a key in the map in the listeners to help us look up F delegate handles for that particular listener, for that particular actor. As now we have three different classes that will broadcast this event. Although in C++, people regularly will use multiple inheritance to get characteristics of multiple parent classes into a particular child class. That's not a good idea here in Unreal. We're going to use a different approach that lets us have our different invoker classes be treated as invoker classes without muddying up our class hierarchy by making each of them inherit from both the unreal actor class in some other class that we defined. The thing that we're going to use is we're going to use something called an interface. Interfaces are commonly used for exactly this purpose in C Sharp. They're not used in C++ for this purpose, people use multiple inheritance. But in Unreal, in C++, we can actually use interfaces so that we still have single inheritance. We have nice class hierarchies where each child only has a single parent class. Over here in my project files, I've actually added an interface. I'll show you how I did that. Over here in the editor, I said I wanted to create a new C++ class, and I scrolled all the way down, and I picked Unreal Interface as the parent class for my interface. I'm not going to do it again. I already have that interface, but that's how I added the interface to my unreal project. I'll show you the points added in Volcker interface implementation file doesn't have anything in it other than the pound include, it does say add default functionality here for any IPointsAddedInvokerInterface functions that are not pure virtual. But I only have one function in this interface, and I've made it pure virtual because I don't know a good default implementation for the function that I've included. Here's what the interface looks like. I have pond included my delegate declarations and the class is marked as UINTERFACE. This comment was automatically provided when Unreal created this script for me. We'll just leave it alone because it says to leave it alone. This is the name of my actual interface. I added the comment, an interface with a dipole invokers of the points added event. This comment was automatically generated. It says Add interface functions to this class. This is the class that will be inherited to implement the interface. We want to get the points added event for this invoker. Just like we implemented a get MessageEvent function in our talker actor class, so that we could get the message event that was inside that talker actor, so that we could add listeners to it. But we're going to make it so the multiple classes that invoke this event need to provide a GetPointsAddedEvent that returns a reference to the FPointsAddedEvent field that will be in those classes. I've marked it as PURE_VIRTUAL. Here's the name of that PURE_VIRTUAL function. This is horrendously ugly code. I will freely admit that's horrendously ugly code because we're returning a reference, but references can't be null in C++. That's what I'd like to return here as my default function that should never get executed, but I can't return a null reference. I had to do that horribly ugly code, and you can read about it here if you want to. This should never get executed because I marked it as PURE_VIRTUAL. I feel guilty, but that's what I had to do to get this to compile. I know because I marked it as PURE_VIRTUAL, that that horribly ugly code should never get executed. This is how I define an interface. Notice of course that I made this not just a virtual function, but a PURE_VIRTUAL function. That will make sure that any of my classes that inherit this interface will have to implement the GetPointsAddedEvent function. Now if we look at my event manager, you can see I've #included the PointsAddedInvokerInterface. Not a specific class, but the interface itself. GameHUD will be my listener, and I have a TArray of pointers to objects that implement that interface. That's my invokers TArray. I have a TMap where I have a pointer to my listener as the key, and the value is another map with a pointer to the object that implements the interface and the FDelegateHandle I got back when I added a you object to the PointsAddedEvent in that particular object. That's my set of listeners. Then really the rest of this looks the same as we looked at when we added an event manager, except that we're always dealing with pointers to the interface. In the implementation file, this all really looks just like we've already looked at. The only thing that I want to mention is right here, we can safely call the GetPointsAddedEvent function on a pointer to an object that implements the interface, because we know that that object has to implement that PURE_VIRTUAL function. Other than the use of the pointers to objects implementing the interface rather than pointers to actors, the rest of the event manager looks just like we've already seen. In our loot actor, we #include the delegate, the header file, and we #include the interface file, so here's where we see the use of that interface. Our loot actor used to just inherit from AActor. But now it inherits from this class, and it also inherits from the interface. Our loot actor inherits all the stuff that it inherited before, but now because we've said it inherits from or we regularly used the terminology that this class implements the interface, because we've said it implements this interface, that means that it's going to provide a GetPointsAddedEvent function. It has to, because we marked that as a PURE_VIRTUAL function. We have a field for the PointsAddedEvent, we're going to override the EndPlay function so when the loot actor gets removed from the level, we can remove it as an invoker for the PointsAddedEvent, and this will happen all the time. In the adding event manager, we actually never removed talkers or listeners from our level. But in the teddy bear destruction game, loot and teddy bears get destroyed all the time. This function will get called each time a loot actor gets destroyed. Here's where we're overriding that get points added event. The rest of this class looks the same. In our implementation file, you'll notice that I commented out our reference to the GameHud header file because this actor no longer needs to know about the GameHud. This actor is just going to work through the event manager actor. I've added the pound include for that header file. In addition to the stuff we did before, we're adding ourselves as invoker to the event Manager. When we get removed from the level, we remove ourselves as an invoker from the event manager. Here's our implementation of that overwritten function where we just return our field, and here's our other different. Instead of what we used to do, which was get a reference to the Hud and then call the Hud's add points function, instead, we're just broadcasting a point added event. Whoever's listening for that event, it will be the GameHud, whoever is listening for that event will just hear that event and process it. Our Teddy bear actor header file looks remarkably similar, where we have some more pound includes, and we say we're going to implement that interface as well as inherit from AActor. Provide event support, handle when the teddy bear gets removed from the level, and override that pure virtual function from the interface in the implementation file. Again, I don't care about the GameHud anymore, but I do care about the event Manager. I add myself as an invoker in Begin play. When it's time to add points, I broadcast the event instead of getting a reference to the Hud and calling that add points function, remove myself when I get removed from the level, and implement the override for the get points added event function from the interface. There's no need for us to look at the Launch upon because it does the same things in the header and the implementation file. The last thing we should look at is the GameHud, which needs a reference to the delegate. I've added begin play to the GameHud because that's where I'm going to tell the event Manager that I'm a listener for the event. I've added an Add to points added event function just like we saw when we were adding an event manager, and even though the game shouldn't be removed from the level, we're going to implement our Endplay function anyway just for completeness. As I said, in begin play we add ourselves as a listener. In our add to points added event function, we do what we've seen before for listeners. We return the FDelegateHandle that we get when we add ourselves as a you object to a particular event, and we remove ourselves as a listener when we are removed from the level, even though that shouldn't happen for our GameHud. I should have pointed out that we're providing the address of our add points function here, and of course our add points function doesn't have to change at all. It just gets called when the event is broadcast, instead of being called directly by the Launcher upon and the teddy bear actor, and the loot actor. And of course I'll show you that the game still works fine after that refactoring. I can still destroy teddy bears and loot, and my score goes up. My Launcher actually deducts points when I collide with teddy bears as well. To recap, in this lecture you learned how to refactor our TeddyBear destruction game, to use events and an event Manager, and you also learned how to use interfaces in Unreal.