In this lecture, we'll see how we can implement events and event handlers in a small game. This game is called Fish Revenge because the fish actually eat the bears, and that's not the way it usually works out for the fish. Let's go take a look at the game. Here's our starting point for today's lecture. I will run the game and you'll see that I can drive my fish around, and I can eat teddy bears, and my score increases when I eat teddy bears so this is a nice twist. I can HUD teddy bears too as you saw. But as you can see, I can score points by eating teddy bears. That's the big idea. The important components here are that I have a HUD, and this HUD has a HUD script attached to it and the fish is the thing that goes around eating teddy bears. In fact, we have a field in the fish script for bear point, so bears are worth ten points as you saw as I played the game. Let's take a look at the code to see how this score display functionality is implemented. Within my HUD script, I have a scoreText, text object, and I have the actual score, and I also have a ScorePrefix that I've saved as a constant because I use that to build the text that's displayed by the scoreText. In the start method, I go find the GameObject with the scoreText tag, and then I get its text component. As you can see back here in the editor, I have the scoreText GameObject selected, and then in the inspector, you can see that I've tagged it with the scoreText. The reason I need to do it this way is because my scoreText field is static, and I needed it to be static because I'm going to access that field from within a static method, and static methods can't access instance variables or fields. They can only access static fields so I have to go find that scoreText object and get the text component attached to it, and then I can set the text of that text object to be that ScorePrefix plus score. Score starts at zero, also I'm going to start with a score of zero. Here's that static method I was talking about. I have an AddPoints method that I've marked as static, and it has one parameter for the points to be added. Here, I add those points to the score, and then I change the text that's displayed to be that ScorePrefix concatenated with the new score. In my fish class, way down near the bottom in my OnCollisionEnter2D method, I have a block of code that destroys the teddy bear if it's collided with the head of the fish so the fish ate it instead of bouncing off the tail or something, and here's where I update score. I call that static method adding bearPoints to my current score. That's our current implementation and the thing we don't like is that the fish has to know about the existence of the HUD. Fish are just fish, they shouldn't have to know about that stuff. Instead, we're going to add an event and an event handler to take care of this and a more object oriented way. Remember from looking at the documentation for a UnityEvent, that we actually have multiple versions of UnityEvent. We can have a zero argument event, we can have a one argument event and so on and the one argument event is the one that we actually need. Now, it turns out that there is a comment in this documentation that says, if you want to use this one, you have to override the class type because notice, this looks just like a generic because it is a generic and we're going to have to say what type we want this to be. For our one argument, we wanted it to be an integer, because we want it to be the points that we're going to add to the score. Let's go implement an event type that is a UnityEvent with a single int argument or parameter. We'll start by adding a script in the editor, and I will call this pointsAddedEvent because it's the event that will get invoked when points are added in the game and here's the standard template that we get when we create a new unity script, and we're going to change this significantly because we'll say here, a point-added event, but this is not going to inherit from MonoBehavior. In fact, this is going to be a UnityEvent, and you'll notice that it won't auto-complete because I need to add a using directive for the namespace for UnityEvents. In the documentation for UnityEvent, you can see that it says it's a class in UnityEngine.Events. That's a namespace. We don't have a using directive for in our new CSharp script. This is an easy fix. I'll add the using directive, and now I'll be able to get visibility into the UnityEvent. And remember, I wanted to be within int, and the rest of this code goes away. That's it. For declaring my new event class as a form of UnityEvent that has a single int argument. The next thing I do, is I go to my fish class, and I'm going to build an instance of this event, and I'm going to expose a way for an event handler, in this case the HUD, to add a listener for that event. I'll do that at the end of the field I have in this class, and it really is still score support so that's where I'll put it. Now, we have declared a new type, a new class called pointAddedEvent, and so I declare this field in the usual way. I put the type name, and I put the variable name. This is one of those cases where I'm using pure CSharp on the UnityEvent class provided by the UnityEngine so I will call the constructor like so. I still need to add the addListener method so the HUD can register, if you will, an event handler to listen for the pointsAddedEvent. I will take that in and then we'll come back. As you can see, as I build the method header for this new method, I'm getting a compilation error over here. If I hover over it, we can see that it doesn't exist in the current context, and I'll just tell you that's because we haven't added a using directive for the events namespace here in the fish script. Once we've done that, the compilation error goes away and I can add this listener as a listener for the pointsAddedEvent field. Everything compiles okay at this point, but the HUD still hasn't added itself as a listener for the event, so we need to go do that next. This AddPoints method actually matches the unity action delegate with one int parameter except that it can't be static. At this point, we don't actually have a reference to the fish object so that we can actually add our listener so I will add the code to do that and then we'll come back. I'm doing this work of adding my event handler as a listener in the start method for the HUD. The first line of code actually gets the Fish Game object, and I went and added a tag to the Fish Game object, and then gets the fish script that's attached as a component to that game object, and puts it into this local variable that I'm just going to use for a moment. I'm then going to call the new method I wrote, although I had to go back and make it public because I forgot to do that, and I'm going to pass in the name of the method that I'm using as my event handler, my listener for the event and this is where it's new rate with the delegates and event handling. I'm not passing in a number or an object, I'm passing in the name of a method. At this point, I can actually make it so these two fields are no longer static because I've changed my AddPoints method to no longer be a static method. Remember, that's the only reason those fields were static. Now when I compile, I get an error in my fish script, and the last change I need to make here, is to no longer try to directly call the HUD AddPoints method here in my fish group, I should just invoke the event instead. I access my pointsAddedEvent object, I call the Invoke method on it. Remember, this event has one integer, and the integer I'll provide is bearPoints. Now, I can run my game again. As we can see, the scores start at zero as it did before, and the scoring works the way it used to except that we've re-factored our code to use events and event handlers instead. Now, the fish doesn't have to know anything about the HUD. The more astute learners watching this lecture could easily say sure, but now the HUD needs to know about the fish, so you really haven't gained anything by doing this event handling. That's partially true. We're comfortable having the HUD to know about the GameObjects at least more so than the sort of active GameObjects in the game, knowing about the HUD, but don't worry. We'll actually make this even better in the next lecture so that neither the HUD nor the fish needs to know about any of the other GameObjects in the game. To recap, in this lecture, we saw how we could replace a static method in the HUD, that let the HUD add points to the score, with an event and an event handler that handles that same functionality for us. It does it in a better object-oriented way than the static method, but it's still not a great object- oriented design, and we will improve on that in the next lecture.