Would you like to inspect the original subtitles? These are the user uploaded subtitles that are being translated:
1
00:00:04,330 --> 00:00:10,300
Hello and welcome in this lecture, we're going to be implementing the observer pattern using unity
2
00:00:10,300 --> 00:00:14,200
events, and if you haven't come across them before, we're going to do a brief overview of them and
3
00:00:14,200 --> 00:00:16,900
see how they fit the observer pattern.
4
00:00:17,200 --> 00:00:24,430
So let's start with an example to really understand how the observer pattern works in practice and what
5
00:00:24,430 --> 00:00:27,220
mechanisms we might use to implement it in unity and C-sharp.
6
00:00:27,370 --> 00:00:34,020
So here we were mentioning that I have a game where you can level up so you can get experience points.
7
00:00:34,030 --> 00:00:40,090
This is a level monitor behavior here, a level component and we've got experience is basically the
8
00:00:40,090 --> 00:00:41,500
only state of this class.
9
00:00:41,500 --> 00:00:45,220
The configuration is how quickly it gains experience over time.
10
00:00:45,220 --> 00:00:50,500
This is just a very simple little hack so that we don't actually have to implement any gameplay where
11
00:00:50,500 --> 00:00:54,820
in this method here, if you're not familiar with routines, this is a code routine.
12
00:00:54,850 --> 00:00:57,720
And what it's doing is you can basically say it like this.
13
00:00:57,730 --> 00:01:03,580
It repeats it loops around a weights two point two seconds and then it gains 10 experience.
14
00:01:03,580 --> 00:01:06,670
So it just keeps gaining experience every point two seconds.
15
00:01:07,030 --> 00:01:11,530
That's how it levels up, and the configuration here is the points per level.
16
00:01:11,590 --> 00:01:15,790
So this is goes back to my point about not caching stuff.
17
00:01:15,790 --> 00:01:22,150
We don't have you noticed a variable that tells you what level you are because you can calculate that
18
00:01:22,150 --> 00:01:23,590
from your experience points.
19
00:01:23,920 --> 00:01:29,710
So if we go down to the level method, you can see that it's simply the experience points divided by
20
00:01:29,710 --> 00:01:31,030
the points per level.
21
00:01:31,270 --> 00:01:34,150
And because these are both integers, this ends up being an integer division.
22
00:01:34,390 --> 00:01:37,990
And if you have less than the points per level, you are level zero.
23
00:01:38,020 --> 00:01:43,000
Once you have, say, 200 points, you then a level one until you have 400 points, then you're level
24
00:01:43,000 --> 00:01:45,310
two, etc. Get experience.
25
00:01:45,580 --> 00:01:46,510
It's pretty straightforward.
26
00:01:46,750 --> 00:01:48,190
Gain experience again.
27
00:01:48,190 --> 00:01:49,060
Pretty straightforward.
28
00:01:49,090 --> 00:01:50,380
Gets it set settings here, really?
29
00:01:50,860 --> 00:01:52,690
So this is a very basic class.
30
00:01:53,080 --> 00:01:59,530
Now we've got a health component, and this health component kind of has some little hacky logic here.
31
00:01:59,530 --> 00:02:03,700
Again, we've got this kind of health drain code routine and all this is doing.
32
00:02:03,700 --> 00:02:09,340
If we're going to have a look at it is it will drain the health down to zero at whatever drains per
33
00:02:09,340 --> 00:02:10,509
second every seconds.
34
00:02:10,509 --> 00:02:12,880
I just remove something from the health every second.
35
00:02:12,880 --> 00:02:18,850
So again, we've got this game played little test for us and at the beginning we reset the health.
36
00:02:18,850 --> 00:02:23,080
So the current health gets reset to the full health in a week.
37
00:02:23,620 --> 00:02:29,500
So then we've got some Getz's and we've got a reset health public method, which we might not want to
38
00:02:29,500 --> 00:02:31,160
be public in the long run.
39
00:02:31,180 --> 00:02:37,450
And then finally, there's a debugger mono behavior, which simply every second is putting out the vital
40
00:02:37,450 --> 00:02:38,300
stances put.
41
00:02:38,360 --> 00:02:42,070
It's logging the experience, get level and get healthy.
42
00:02:42,880 --> 00:02:46,120
So if you run this, it really does not do very much.
43
00:02:46,330 --> 00:02:51,160
You can see in the sample seen here, we've got the observer example and we've got a possible system.
44
00:02:51,160 --> 00:02:56,440
If you go ahead and just play, the political system doesn't run by default.
45
00:02:56,800 --> 00:03:02,530
It's been set up to not run on a wake, and we've just got our log messages down here saying the experience.
46
00:03:02,530 --> 00:03:07,210
As it goes up and up and up, you can see the level that's being calculated and printed here.
47
00:03:07,270 --> 00:03:13,060
That's working, as I explained, and the health, which is just steadily decreasing and decreasing
48
00:03:13,060 --> 00:03:13,810
and decreasing.
49
00:03:14,500 --> 00:03:23,470
Now suppose that in my game, I wanted to implement behavior where my health gets reset whenever I level
50
00:03:23,470 --> 00:03:23,770
up.
51
00:03:24,580 --> 00:03:31,720
Now the naive way to do this, if you didn't know about the observer pattern, would be to go into level
52
00:03:31,720 --> 00:03:37,120
and say, OK, well, whenever I gain experience, I need to check whether I have leveled up.
53
00:03:37,120 --> 00:03:41,050
So before I gain the experience, I'm going to keep a note of what my level was.
54
00:03:41,050 --> 00:03:45,460
So I'll say that the level is equal to get level when I start off.
55
00:03:45,460 --> 00:03:48,490
So that's kind of made a copy of that initial level.
56
00:03:48,850 --> 00:03:54,670
And then after I've gained experience, I can simply say if the new level so get level is greater than
57
00:03:54,670 --> 00:04:01,300
level, then I can do whatever it was I wanted to do, which in this case would be to get components
58
00:04:01,300 --> 00:04:06,310
of type health and to call reset health on that.
59
00:04:06,610 --> 00:04:10,450
Obviously, this has created a link that doesn't really make sense.
60
00:04:10,450 --> 00:04:17,860
I mean, why should the level component know anything about health is is a rule more about the health
61
00:04:17,860 --> 00:04:23,230
components, more that the health component wants to be reset when level levels up.
62
00:04:23,650 --> 00:04:28,090
So instead of doing this, what you could do is remove all this logic from here.
63
00:04:28,090 --> 00:04:32,350
I'm just going to come and sit out for a second because we will need this in a little while.
64
00:04:32,890 --> 00:04:41,950
And what you can do instead is you could go ahead and go over to health and you could decide that we're
65
00:04:41,950 --> 00:04:47,230
going to reset health by polling, polling, basically being checking every frame.
66
00:04:47,590 --> 00:04:52,930
So we would go into here after a while cut out an update method in this update method.
67
00:04:52,990 --> 00:04:57,910
First of all, I need to be keeping track of the current level to see whether I've leveled up so far.
68
00:04:58,180 --> 00:05:02,860
For a start, I'm going to have to create a kind of extra piece of state in health to do with level,
69
00:05:02,860 --> 00:05:03,820
which is weird.
70
00:05:04,040 --> 00:05:05,060
But we'll get to that in a second.
71
00:05:05,780 --> 00:05:11,120
Then we're going to have the last call at last level, that piece of state.
72
00:05:11,180 --> 00:05:19,190
I'm going to set to zero, but I'm actually going to initialize it in start if we access other things
73
00:05:19,550 --> 00:05:21,290
we shouldn't do in a way, Krista and start.
74
00:05:21,320 --> 00:05:24,560
So we're going to get components of top level.
75
00:05:26,080 --> 00:05:34,210
Don't get level, we're going to initialize last level to that value and then in update, what we're
76
00:05:34,210 --> 00:05:45,910
going to do is if last level is less than current level and I need to get the current level into a variable
77
00:05:45,910 --> 00:05:52,320
and say, let's do an its current level is equal to this same line here.
78
00:05:52,330 --> 00:05:54,670
Get component level, get level notice.
79
00:05:54,940 --> 00:05:57,160
I'm not caching this level component here.
80
00:05:57,160 --> 00:05:58,780
I'm just getting it when I want it.
81
00:05:59,230 --> 00:06:03,730
And then if we have increased, then we need to store a new last level.
82
00:06:03,730 --> 00:06:08,140
First of all, so last levels equal to current levels so that we don't go resetting every single frame.
83
00:06:08,470 --> 00:06:09,910
And then you can call reset health.
84
00:06:10,270 --> 00:06:16,900
This is complicated and it is polling, which means that this is happening every single frame we're
85
00:06:16,900 --> 00:06:23,380
having to check and get the other level and compare, even though we arguably could know when we did
86
00:06:23,380 --> 00:06:24,110
it the other way.
87
00:06:24,340 --> 00:06:27,320
Then we called it from level that was much more efficient.
88
00:06:27,340 --> 00:06:29,590
It was just the dependencies were all wrong.
89
00:06:29,620 --> 00:06:34,270
So what we want to do is for us to be able to subscribe.
90
00:06:34,270 --> 00:06:36,460
This is a perfect example of the observed pattern.
91
00:06:36,700 --> 00:06:38,320
We've got something that we want to observe.
92
00:06:38,320 --> 00:06:43,210
The subject, which is level and the observer is health and wants to observe that level.
93
00:06:43,720 --> 00:06:44,760
So how can we do that?
94
00:06:44,770 --> 00:06:52,270
Well, one way that you can do this in Unity exclusively is using something called a unity event.
95
00:06:52,300 --> 00:06:57,580
Now I'm going to start with this because although it might not be the most obvious suggestion, it is
96
00:06:57,580 --> 00:06:58,900
quite easy to understand.
97
00:06:59,170 --> 00:07:04,090
So what you can do is you can create a serialized field that has the tight unity.
98
00:07:05,010 --> 00:07:11,740
Event and we can call it something like on level up, and you don't have to give it any value at all
99
00:07:11,740 --> 00:07:14,970
that automatically gets set up correctly by unity.
100
00:07:15,540 --> 00:07:19,320
So on level up now, what are we going to do with on level up?
101
00:07:19,800 --> 00:07:23,520
Well, let's uncomment this coat that we had in gain experience.
102
00:07:23,730 --> 00:07:31,350
And when we do level up, we can detect that on Line 24 with that if statement we can do on level up
103
00:07:31,350 --> 00:07:32,370
dot invoke.
104
00:07:33,480 --> 00:07:37,680
So you see that on the on the unity event has this invoke functionality.
105
00:07:38,070 --> 00:07:46,020
Now what that does is it essentially calls a notification on anybody who's listening to this unity event.
106
00:07:46,710 --> 00:07:50,010
Now how do we go and listen to the event while there's ways of doing it?
107
00:07:50,010 --> 00:07:52,860
But the obvious way is to do this in the inspector.
108
00:07:52,920 --> 00:08:00,840
That's why I've made it a serialized field so I can go ahead and remove this start code and update code.
109
00:08:00,850 --> 00:08:01,830
We don't need that anymore.
110
00:08:02,970 --> 00:08:03,600
Let's get rid of that.
111
00:08:04,080 --> 00:08:07,710
We can get rid of the extra state that we included there as well.
112
00:08:08,430 --> 00:08:09,150
We don't need that.
113
00:08:09,360 --> 00:08:12,780
And then we head into unity, let it recompile itself.
114
00:08:12,780 --> 00:08:19,590
And if you go to the observer example game object, then essentially what we can do is this level script
115
00:08:20,130 --> 00:08:26,250
now has this on level up section, and you can add items to this list of observers.
116
00:08:26,250 --> 00:08:33,419
And basically, what that's going to do is everything in this list will get cooled when we level up.
117
00:08:33,600 --> 00:08:36,450
So, for example, we've got a particle system here.
118
00:08:36,900 --> 00:08:43,230
You can link all sorts of gameplay events to this on level up event so I can drag in my particle system
119
00:08:43,230 --> 00:08:46,110
game object into the object, the target object to run.
120
00:08:46,770 --> 00:08:49,800
And then with the function, I need to go ahead and select that.
121
00:08:49,800 --> 00:08:56,400
I wants to run a function on the particle system components and then I need to go down to whichever
122
00:08:56,400 --> 00:08:57,250
function I want to run.
123
00:08:57,270 --> 00:09:03,780
This case is going to be the play, and what we can do now is observe that if we go ahead and hit play
124
00:09:04,590 --> 00:09:10,530
and we're gaining experience periodically, you should see the log messages down here when we reach
125
00:09:10,530 --> 00:09:11,070
200.
126
00:09:11,340 --> 00:09:15,500
You can see it played a particle effect, a signal that I leveled up.
127
00:09:15,510 --> 00:09:18,120
I level up again plays a particle effect again.
128
00:09:18,120 --> 00:09:23,700
So every so often it's playing a particle effect in response to that unity event.
129
00:09:23,730 --> 00:09:30,120
This is the observer pattern in action, except it's an observer pattern that isn't fully realized in
130
00:09:30,120 --> 00:09:37,410
code is configured using the unity event configured using the Unity editor.
131
00:09:37,620 --> 00:09:43,540
So here's a challenge for you to replenish the health using this unity event that we have just created.
132
00:09:43,560 --> 00:09:48,990
Go ahead and add the unity event in that code that I was writing the first part of the lecture to the
133
00:09:48,990 --> 00:09:54,600
code that you can download as a resource against this lecture, then add a unity event.
134
00:09:54,600 --> 00:09:56,210
Call back a new one.
135
00:09:56,220 --> 00:09:58,750
We've got one talking to the particle system at a new one.
136
00:09:58,770 --> 00:10:04,050
Hook it up to the observer example game object and call the reset health method.
137
00:10:04,350 --> 00:10:06,000
So pause video and have a go.
138
00:10:10,470 --> 00:10:11,010
OK.
139
00:10:11,040 --> 00:10:11,700
Welcome back.
140
00:10:11,970 --> 00:10:13,390
So how are we going to do this?
141
00:10:13,410 --> 00:10:20,340
Well, we're going to start off by going into unity because we set up these unity events that we're
142
00:10:20,340 --> 00:10:21,480
going to add a new call back.
143
00:10:21,720 --> 00:10:25,970
We're going to drag the observer example as the game object targets in here.
144
00:10:25,980 --> 00:10:27,500
Then we're going to go select function.
145
00:10:27,510 --> 00:10:31,230
You can see it's showing us the components are available on that game object.
146
00:10:31,650 --> 00:10:32,970
We need to find the health component.
147
00:10:32,970 --> 00:10:37,470
We need to get to the reset health and they go, we're now calling reset health when we level up, so
148
00:10:37,470 --> 00:10:39,600
if we go ahead and hit play.
149
00:10:41,460 --> 00:10:47,220
Then you can see we're gaining experience, then we level up and our health goes back up to maximum,
150
00:10:47,220 --> 00:10:52,650
so we're not we're constantly draining the health, but it also gets reset every time we level up.
151
00:10:52,860 --> 00:10:53,340
Great stuff.
152
00:10:53,340 --> 00:10:57,630
So that shows us how the observer pattern can be implemented using unity events.
153
00:10:58,020 --> 00:11:06,120
In the next lecture, we're going to look at how we can implement it using delegates and actions using
154
00:11:06,120 --> 00:11:07,350
pure C-sharp.
16304
Can't find what you're looking for?
Get subtitles in any language from opensubtitles.com, and translate them here.