Would you like to inspect the original subtitles? These are the user uploaded subtitles that are being translated:
1
00:00:04,280 --> 00:00:10,160
Hello and welcome in this lecture, we're are going to be looking at how we could replace the unity
2
00:00:10,160 --> 00:00:15,470
specific unity event with a more C-sharp generic event action.
3
00:00:15,830 --> 00:00:18,830
And we'll see the pros and cons of using that approach.
4
00:00:19,100 --> 00:00:21,050
Let's dive in and see it now.
5
00:00:21,590 --> 00:00:26,450
So we've seen how we can implement the observer pattern using agency events.
6
00:00:26,750 --> 00:00:35,210
However, that does require us to go in and set this up in the ED. And that means that if we use a health
7
00:00:35,210 --> 00:00:39,200
component and forget to set it up, this behavior is not going to exist.
8
00:00:39,200 --> 00:00:42,530
That might be fine for you and you might not want it to always exist.
9
00:00:43,070 --> 00:00:49,930
But if you want a certain behavior to always exist and be configured in code, then you can still use
10
00:00:49,960 --> 00:00:50,600
the unity event.
11
00:00:50,600 --> 00:00:53,420
There is a way to subscribe to a unity event in code.
12
00:00:53,930 --> 00:01:00,230
That's one thing that we could do, but there is a built in mechanism in C Sharp that we could use as
13
00:01:00,230 --> 00:01:00,430
well.
14
00:01:00,440 --> 00:01:04,580
So let's, first of all, have a look at how we might do this in code.
15
00:01:04,849 --> 00:01:10,550
So taking the serialised field and turning into public will expose our own level up.
16
00:01:10,610 --> 00:01:14,960
I have accidentally just gone ahead and closed that file, so let's go open it again.
17
00:01:15,470 --> 00:01:17,450
So we've now got on level up exposed.
18
00:01:17,450 --> 00:01:21,310
So in health, we should be able to register here.
19
00:01:21,320 --> 00:01:26,240
So we're going to do this and start because we need to get hold of another component and we should only
20
00:01:26,510 --> 00:01:28,910
get hold of and communicate with other components in start.
21
00:01:29,360 --> 00:01:31,520
But do it get component level?
22
00:01:32,330 --> 00:01:37,250
And then we are going to look for the on level public variable unity event.
23
00:01:37,310 --> 00:01:42,470
And from then we can go and see what options we've got and we've got an add listener.
24
00:01:43,040 --> 00:01:47,870
You can think of a listener as being a bit like an observer lazy listener.
25
00:01:47,880 --> 00:01:51,250
You can substitute observer if you like, so we can add a listener.
26
00:01:51,260 --> 00:01:57,680
And then what you need to pass in here is a function for it to call so we could pass a reset health.
27
00:01:58,070 --> 00:02:04,370
And it's important here that you leave off the set of parentheses because what we're doing here is we're
28
00:02:04,370 --> 00:02:08,009
saying cool this method when on level up is invoked.
29
00:02:08,690 --> 00:02:13,250
If we put parentheses after here, we would be calling the method right now in stop.
30
00:02:13,250 --> 00:02:14,330
But that's not what we want to happen.
31
00:02:14,360 --> 00:02:17,000
We want that method to be called on level up.
32
00:02:17,120 --> 00:02:19,370
So we need to leave off the parentheses.
33
00:02:20,090 --> 00:02:23,720
So that's the way that we can do it with a unity event, and that's OK.
34
00:02:24,080 --> 00:02:27,500
But there are a few things that are not so great about this.
35
00:02:27,500 --> 00:02:34,280
The first is that this on level up variable has a lot of other methods that are completely unprotected.
36
00:02:34,580 --> 00:02:40,340
For example, I can do on level up dots invoke so I could call the owner level up event.
37
00:02:40,370 --> 00:02:45,350
Now, obviously, I wouldn't try and do this, but you can see that it's not very well protected.
38
00:02:45,350 --> 00:02:46,820
It's not very well encapsulated.
39
00:02:46,820 --> 00:02:49,040
I could also remove all listeners.
40
00:02:49,370 --> 00:02:52,580
That's not very good for the health component to be able to do so.
41
00:02:52,580 --> 00:03:00,080
All these things are fixed by a C-sharp mechanism called an event, and an event automatically protects
42
00:03:00,080 --> 00:03:00,400
you.
43
00:03:00,410 --> 00:03:06,560
It allows you to publicly expose subscribing to an event and subscribing yourself.
44
00:03:06,860 --> 00:03:09,790
But you can't remove anybody else's listeners.
45
00:03:09,800 --> 00:03:15,050
You cannot invoke the method that can only be done from the place that declares it.
46
00:03:15,410 --> 00:03:18,710
So that sounds like exactly the sort of thing we want to be able to do.
47
00:03:19,370 --> 00:03:25,670
So let's go ahead and put our unity event back to being a sterilize field like soap, and let's create
48
00:03:25,670 --> 00:03:31,370
another on level up event here, which we're going to have as our own level up action.
49
00:03:31,490 --> 00:03:32,630
You'll see why in just a second.
50
00:03:32,810 --> 00:03:38,870
The way we declare this is and I'm going to put this after all of our state, we have a public variable
51
00:03:38,870 --> 00:03:41,840
that we call put the event key word in front of.
52
00:03:41,840 --> 00:03:48,020
And then we're just going to use the type action for now, and we'll get to that in a second.
53
00:03:48,050 --> 00:03:53,390
Now you do need to be using system in order to use action or you can use system action.
54
00:03:54,020 --> 00:03:59,660
So we've got a public event action and then we can have on level up action.
55
00:03:59,660 --> 00:04:02,360
I'm going to call it just to differentiate from the other one.
56
00:04:02,450 --> 00:04:08,870
Now what we can do with on level up action is we can actually just call it like a method.
57
00:04:09,080 --> 00:04:13,130
So if we go down, it's gain experience where we are invoking own level up.
58
00:04:13,430 --> 00:04:18,920
We can also do on level up action and we can just put parentheses on the end of it and call it like
59
00:04:18,920 --> 00:04:19,070
this.
60
00:04:19,070 --> 00:04:20,630
So we don't have to do a dot invoke.
61
00:04:20,640 --> 00:04:23,690
You can just call it like this because it's built into the C-sharp language.
62
00:04:23,930 --> 00:04:26,910
It has some niceties around it, so you can do like this.
63
00:04:26,930 --> 00:04:27,440
It does.
64
00:04:27,440 --> 00:04:28,970
However, this would give an error.
65
00:04:29,060 --> 00:04:36,050
If there is nothing listening to this event, then it's going to give an error when we call this.
66
00:04:36,290 --> 00:04:39,740
So typically what you do is you will wrap this and if statement.
67
00:04:39,740 --> 00:04:46,460
So you say if on level up action and you notice that's quite cool, there is a little lightning bolt
68
00:04:46,460 --> 00:04:50,300
in auto complete and visual studio code, which basically signifies that it's an action.
69
00:04:50,300 --> 00:04:54,980
You may have seen these in other built in unity things, so you can put this inside of these statements
70
00:04:54,980 --> 00:04:59,080
and then you can call on level up, call the method from here.
71
00:04:59,090 --> 00:05:03,440
And I was wrong that you can't put it directly if you need say is.
72
00:05:03,780 --> 00:05:05,190
Not equal to no.
73
00:05:05,400 --> 00:05:10,140
So we're saying that if on a level up action is not equal to now, you can go ahead and call it like
74
00:05:10,140 --> 00:05:10,470
so.
75
00:05:10,680 --> 00:05:14,690
Now the flip side to this would be registering for that event.
76
00:05:14,700 --> 00:05:17,850
So actually being able to go ahead and listen to it.
77
00:05:18,390 --> 00:05:22,130
We can do this over in health now.
78
00:05:22,140 --> 00:05:25,890
We've not got on level up exposed anymore, so we need to stay on level up action.
79
00:05:25,920 --> 00:05:31,680
You can see it now says on level up action, it gives us that little thunderbolts, which tells us right
80
00:05:31,680 --> 00:05:32,970
off the bat that this is an action.
81
00:05:32,970 --> 00:05:33,900
We can subscribe to it.
82
00:05:34,440 --> 00:05:41,130
And then what you do is you use this interesting syntax to do plus equals and then you have the name
83
00:05:41,130 --> 00:05:44,100
of the method you wanted to call, such as reset health.
84
00:05:44,550 --> 00:05:50,150
So this does exactly the same thing as when we did add listener, except the syntax is slightly different
85
00:05:50,160 --> 00:05:51,660
and in my opinion, quite nice.
86
00:05:52,260 --> 00:05:59,490
So what this is doing is it's saying on start, go ahead and add this reset health listener and this
87
00:05:59,490 --> 00:06:04,040
will be called whenever the level up event happens.
88
00:06:04,050 --> 00:06:06,480
So you don't need to do this anymore.
89
00:06:06,720 --> 00:06:13,230
Over in years, he don't need to configure this so we can go ahead and remove the reset health call
90
00:06:13,290 --> 00:06:15,000
from the inspector.
91
00:06:15,450 --> 00:06:16,890
And that's great.
92
00:06:17,070 --> 00:06:19,530
We are now getting the same sort of functionality.
93
00:06:19,830 --> 00:06:27,240
However, let's just check, is there any way that we could abuse this that's going to unlevel up to
94
00:06:27,540 --> 00:06:28,770
action dots?
95
00:06:28,800 --> 00:06:31,020
Well, should we can't do any dots here?
96
00:06:31,020 --> 00:06:33,090
There's no kind of dots to be done.
97
00:06:33,450 --> 00:06:38,550
What we can do is we can remove a listener, we could remove the listener for reset health.
98
00:06:38,970 --> 00:06:45,390
And that's something that we might well actually want to do because the standard way of doing this in
99
00:06:45,390 --> 00:06:48,630
unity is not to do this in start.
100
00:06:49,050 --> 00:06:56,610
Reason being, you might start with a component disabled and you probably don't want that component
101
00:06:56,610 --> 00:06:59,160
to have functions called on it if it's disabled.
102
00:06:59,550 --> 00:07:05,400
So what we typically do is instead of using start we use on Enable, which does get called in start
103
00:07:05,400 --> 00:07:08,190
if your component is enabled at the beginning of play.
104
00:07:08,910 --> 00:07:16,980
So then on an able means that we enable the health component or we get started and we then subscribe
105
00:07:16,980 --> 00:07:19,530
to having our callback called.
106
00:07:19,740 --> 00:07:26,220
So I'd like you to experiment with removing that callback on disabled so added on disabled events if
107
00:07:26,220 --> 00:07:27,000
you don't know how to do that.
108
00:07:27,090 --> 00:07:33,300
It's exactly the same as the on enable event I just did, but with the words on disabled instead and
109
00:07:33,300 --> 00:07:40,890
then use the minus equal operator to remove that reset health listener and check the behavior in game.
110
00:07:40,890 --> 00:07:44,580
If you go in play the game and disabled a health component while you're playing.
111
00:07:45,240 --> 00:07:45,990
What happens?
112
00:07:45,990 --> 00:07:47,850
Does that callback get called any more?
113
00:07:47,850 --> 00:07:50,190
Does their health stop being reset?
114
00:07:50,520 --> 00:07:51,180
Have a go.
115
00:07:51,180 --> 00:07:51,810
Find out.
116
00:07:51,900 --> 00:07:53,160
Pause VIDEO And a half ago.
117
00:07:57,480 --> 00:08:00,690
OK, let's go back in and give this a stab.
118
00:08:01,020 --> 00:08:03,480
I'm going to do it on disable.
119
00:08:03,900 --> 00:08:11,310
We're going to do basically the exact same code, so it's going to be a get component level dot on level
120
00:08:11,310 --> 00:08:14,370
up action minus Eq., the reset health.
121
00:08:14,370 --> 00:08:19,710
This time now, actually, because we're not calling Reset Health from outside anymore.
122
00:08:19,710 --> 00:08:23,550
And it's probably not the sort of thing we want just anybody to be able to call.
123
00:08:23,550 --> 00:08:26,100
I'm going to go ahead and make that private.
124
00:08:26,370 --> 00:08:32,100
And you can do that now, so the level doesn't need it to be public because nobody is using that public
125
00:08:32,100 --> 00:08:32,730
interface.
126
00:08:32,730 --> 00:08:37,860
The only public interface here is the fact level exposes an on level up action.
127
00:08:38,190 --> 00:08:42,720
And this is the right way, in my opinion, for the dependencies to be going from health to level,
128
00:08:42,720 --> 00:08:47,310
not the other way round, even though the direction of execution is the other way.
129
00:08:47,310 --> 00:08:51,900
Round level is calling to us, but it doesn't have to know anything about it.
130
00:08:51,900 --> 00:08:54,210
That's a great thing about the observer pattern.
131
00:08:54,210 --> 00:08:57,750
Is it because it flips those dependencies around when you want them to?
132
00:08:58,440 --> 00:08:59,790
So this should now work.
133
00:08:59,790 --> 00:09:07,350
Let's go over into unity, and we're going to make sure that the game isn't going to maximize on load
134
00:09:07,560 --> 00:09:09,430
and go into our console.
135
00:09:09,870 --> 00:09:12,630
Clear it out and we're going to go ahead and hit play.
136
00:09:13,230 --> 00:09:17,730
So when we go ahead and hit play, it's got to maximize it.
137
00:09:17,730 --> 00:09:19,050
For some reason, I don't know why.
138
00:09:19,290 --> 00:09:22,350
And you can see we're getting our log messages out here.
139
00:09:22,740 --> 00:09:29,160
And what I want to do is just go ahead and disable the health component for a time, and we're going
140
00:09:29,160 --> 00:09:35,100
to see that the health component carries on running because the code routine is running that, don't
141
00:09:35,100 --> 00:09:40,020
worry, that's a bug with my implementation there, but you can quite clearly see that the health is
142
00:09:40,020 --> 00:09:41,250
not being replenished.
143
00:09:41,250 --> 00:09:46,440
So we have successfully removed ourselves as a subscriber to the level up event.
144
00:09:46,770 --> 00:09:52,860
However, if I go ahead and re-enable it and we level up, you can see the event is being called once
145
00:09:52,860 --> 00:09:58,050
again and that's entirely being configured now in code using events and actions.
146
00:09:58,440 --> 00:10:04,530
Now, I did promise that we would go back to reviewing this action type here.
147
00:10:04,860 --> 00:10:08,490
So if I go to level and have a look, we've got this action type now.
148
00:10:08,520 --> 00:10:15,690
Basically, this is a easy way of describing a delegate type.
149
00:10:16,110 --> 00:10:18,720
And so this is going to get a little bit technical now.
150
00:10:18,720 --> 00:10:22,020
If you if you're not interested, action is all you need.
151
00:10:22,800 --> 00:10:29,700
However, if you are interested, essentially what action is doing here is is writing the following
152
00:10:29,700 --> 00:10:36,930
we can write delegate void and let's just call it call back type here puts some parentheses like that
153
00:10:36,930 --> 00:10:42,990
and a semicolon so you can see this looks very much like a method declaration, except has this delegate
154
00:10:42,990 --> 00:10:44,190
key word in front.
155
00:10:44,550 --> 00:10:52,830
Now what this is doing is it's telling us the type of method that you can have as a listener to an event
156
00:10:52,830 --> 00:10:53,550
of this type.
157
00:10:53,550 --> 00:11:00,420
So if I replaced action with callback type, the effect is exactly the same because action essentially
158
00:11:00,420 --> 00:11:02,880
is doing that same thing over there.
159
00:11:02,910 --> 00:11:06,750
The only thing you have to watch out for is that the level of accessibility of that type.
160
00:11:06,900 --> 00:11:10,350
The callback type has to be the same as the level accessibility of the event.
161
00:11:10,650 --> 00:11:13,420
So we need to make it a public delegate void, callback type.
162
00:11:13,950 --> 00:11:21,810
And what this is now saying is that anything that has this kind of format, it returns void and it takes
163
00:11:21,810 --> 00:11:27,180
no arguments that can be used as a listener for the on level up action.
164
00:11:27,540 --> 00:11:33,720
Now, if you wanted to, you could have a delegate which has got parameters in here, so it could have
165
00:11:33,720 --> 00:11:38,820
a float, which I don't know could be the level, for example, that we've leveled up to.
166
00:11:38,820 --> 00:11:43,620
And now you can see over in health it would be giving us an error because it's saying, Hey, reset
167
00:11:43,620 --> 00:11:47,460
health doesn't match the delegate, it doesn't take a parameter.
168
00:11:47,460 --> 00:11:52,200
So we'd have to take a parameter like float level for it to stop giving us warnings here.
169
00:11:52,440 --> 00:11:56,400
But obviously we don't want to do that and it was fine just as it was.
170
00:11:56,400 --> 00:12:01,320
So we're going to go back to removing that parameter from our callback type.
171
00:12:01,650 --> 00:12:07,560
You could also have delegates can be used as just parameters into regular functions if you wanted to
172
00:12:07,560 --> 00:12:12,330
pass in a callback for to be called when a function finishes or anything like that.
173
00:12:12,570 --> 00:12:18,690
Delegates are much more widely applicable in the observer pattern, and you don't have to worry about
174
00:12:18,690 --> 00:12:20,610
that if you just want to implement the observed pattern.
175
00:12:20,880 --> 00:12:26,700
I would recommend using action because it avoids you having to invent a name for something that has
176
00:12:26,700 --> 00:12:28,230
already been invented.
177
00:12:28,530 --> 00:12:31,920
If you are a C-sharp developer, you will have come across action.
178
00:12:32,070 --> 00:12:36,000
So this is something that keeps our code clean.
179
00:12:36,000 --> 00:12:36,960
It already has a meaning.
180
00:12:36,960 --> 00:12:39,060
We don't need to reinvent the wheel here.
181
00:12:39,330 --> 00:12:44,850
If you do want to pass an argument, you still don't need to make a new delegate type because action
182
00:12:44,850 --> 00:12:52,380
has a generic format where you put these angle brackets and you could put an action float.
183
00:12:52,800 --> 00:12:55,860
And this basically does exactly the same as that delegate.
184
00:12:55,860 --> 00:12:56,970
I just described it.
185
00:12:57,070 --> 00:13:01,890
Now means that on level up action expects to take a float.
186
00:13:02,640 --> 00:13:08,160
So both the reset health would have to have a float in it, but also where we are calling, it's down
187
00:13:08,160 --> 00:13:15,030
here on line 32 and gain experience that would also have to give you the level that would have to give
188
00:13:15,030 --> 00:13:16,290
you a float in there.
189
00:13:16,290 --> 00:13:20,430
So we'd have to do something like get level to satisfy the compiler here.
190
00:13:21,060 --> 00:13:23,280
So that's a little brief foray into actions.
191
00:13:23,280 --> 00:13:25,740
Obviously, I've brushed over them really, really quickly.
192
00:13:25,740 --> 00:13:31,170
I'm just going to take away that generic argument for float so that we're going back to having an action
193
00:13:31,410 --> 00:13:37,440
that simply signals that something has happened and this is the most used form of action.
194
00:13:37,740 --> 00:13:43,440
So if you see around the place event action, this is a common way of implementing the observer pattern
195
00:13:43,440 --> 00:13:44,520
in C-sharp.
20468
Can't find what you're looking for?
Get subtitles in any language from opensubtitles.com, and translate them here.