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:12,530
So refactoring our code from this model that deals with everything, including UI to a model and a presenter
2
00:00:12,530 --> 00:00:17,240
and a view is going to be relatively straightforward because essentially what we've got here is this
3
00:00:17,240 --> 00:00:21,470
level represents both the model and the presenter all wrapped into one.
4
00:00:21,470 --> 00:00:27,290
It's dealing with UI logic, but also the game logic, whereas the view is already set essentially because
5
00:00:27,290 --> 00:00:28,880
that's what Unity deals with.
6
00:00:28,880 --> 00:00:33,990
The View is the bit that does all the rendering and deals with the inputs, events, et cetera.
7
00:00:34,490 --> 00:00:40,850
So what we're going to do is we're going to pull out a level presenter object and we're going to stick
8
00:00:40,850 --> 00:00:45,080
that directly on the UI, and that's going to deal with all of the binding.
9
00:00:45,560 --> 00:00:48,200
So this should be fairly straightforward.
10
00:00:48,200 --> 00:00:56,360
Let's go in and add a new folder under patterns which are going to call the UI and under their gains,
11
00:00:56,360 --> 00:01:00,490
create a new file, which I'm going to call the level of presenter access.
12
00:01:00,500 --> 00:01:05,060
And in here, we're going to create a mono behavior, which is going to be the level presenter.
13
00:01:05,450 --> 00:01:11,960
And we know from the arrows in our diagrams that the level presents is going to have references to the
14
00:01:11,960 --> 00:01:14,930
model, but also to the view.
15
00:01:15,290 --> 00:01:18,140
So we're going to have a serialized field.
16
00:01:18,140 --> 00:01:23,480
I'm just going to pop back into unity to nudge my auto complete into working.
17
00:01:23,930 --> 00:01:29,560
So we'll have a serialized field, which refers to the level object.
18
00:01:30,740 --> 00:01:37,670
We'll just call that the level, and we want to take all of the functionality in level that has to do
19
00:01:37,670 --> 00:01:38,600
with the UI.
20
00:01:38,960 --> 00:01:45,320
So one thing that I'm going to do is I'm going to rip out the using statements for events and UI to
21
00:01:45,320 --> 00:01:50,600
kind of give us a hint at where we are using stuff that we shouldn't be using.
22
00:01:50,600 --> 00:01:55,820
Actually, we didn't want to take out events, just the UI layer stuff, and you can see it's giving
23
00:01:55,820 --> 00:02:01,320
me squiggles under the text and button types because those are UI types.
24
00:02:01,340 --> 00:02:05,210
We shouldn't have anything to do with those UI types in a model.
25
00:02:05,450 --> 00:02:12,250
So we're going to pull those out and there's three of them and we're going to stick them in to the level
26
00:02:12,260 --> 00:02:13,070
presenter.
27
00:02:13,520 --> 00:02:14,930
So this now makes sense.
28
00:02:15,050 --> 00:02:20,390
The arrows of our dependency from our presenter match up with the arrows from the diagram in the last
29
00:02:20,390 --> 00:02:20,880
lecture.
30
00:02:20,900 --> 00:02:28,490
We've got a dependency on our model and three dependencies here into our view, which is essentially
31
00:02:28,490 --> 00:02:30,440
the canvas hierarchy.
32
00:02:30,590 --> 00:02:38,090
So what we're going to do here is we need to take a little bit more action in order to take a UI update
33
00:02:38,090 --> 00:02:43,790
UI out and to take the increase button binding in here out as well.
34
00:02:44,240 --> 00:02:48,020
So first of all, the button binding, this is relatively straightforward.
35
00:02:48,020 --> 00:02:55,730
I just needs to create a start method in level presenter and then we want to put our cut and paste increase
36
00:02:55,730 --> 00:02:58,280
XP button binding into here.
37
00:02:58,670 --> 00:03:05,660
And we want to, instead of calling, gain experience just on ourselves, we could introduce our own
38
00:03:05,660 --> 00:03:08,660
gain experience method in here.
39
00:03:09,020 --> 00:03:13,010
We're going to just go ahead and generate that method locally as a private variable.
40
00:03:13,010 --> 00:03:19,280
And within that, we can just call level dot gain experience 10, because that's a publicly accessible
41
00:03:19,280 --> 00:03:19,910
function.
42
00:03:20,150 --> 00:03:21,440
And that's fine.
43
00:03:21,440 --> 00:03:27,140
The model does present us with an interface of how we can gain experience.
44
00:03:27,470 --> 00:03:28,250
So that's fine.
45
00:03:28,520 --> 00:03:35,360
Now, the other thing we want to do is essentially have some sort of private void method called Update
46
00:03:35,360 --> 00:03:44,720
UI in here, and we want to take the implementation essentially of Update UI out of or cut it out from
47
00:03:44,720 --> 00:03:49,370
the level module and put it into the level presenter like so.
48
00:03:49,730 --> 00:03:50,960
So that works.
49
00:03:50,960 --> 00:03:56,240
Except now we need to be, instead of calling get level, we need to be calling level dot level and
50
00:03:56,240 --> 00:03:59,340
level Dot's experience experience.
51
00:03:59,600 --> 00:04:01,220
And now the final piece of the puzzle.
52
00:04:01,310 --> 00:04:04,160
When do we actually call Update UI?
53
00:04:04,400 --> 00:04:11,720
Well, one naive implementation would have it called in update, but obviously we don't update the experience
54
00:04:11,720 --> 00:04:12,590
every frame.
55
00:04:12,800 --> 00:04:14,480
So that's a little bit wasteful.
56
00:04:14,750 --> 00:04:20,720
So the way we want to do this is instead in the places where we were previously calling Update UI,
57
00:04:21,050 --> 00:04:27,200
we want to break that link so that model is not dependent upon the level presenter.
58
00:04:27,860 --> 00:04:33,290
So the way we're going to do this is with an observer pattern, which we've already done this with the
59
00:04:33,290 --> 00:04:35,480
action for on level up action.
60
00:04:35,480 --> 00:04:44,240
So I'm going to create a new public event type action, which is going to be on experience change and
61
00:04:44,240 --> 00:04:46,910
on experience changes, essentially what we want to call here.
62
00:04:47,120 --> 00:04:55,970
So in start, we're going to do and if on experience changes, not now we want to call on experience
63
00:04:55,970 --> 00:05:01,570
change and we want to do the same thing down here where we were previously calling Update UI.
64
00:05:01,580 --> 00:05:03,700
If we gain experience, we're going to do on experience.
65
00:05:03,810 --> 00:05:04,800
Change there as well.
66
00:05:04,920 --> 00:05:10,860
So in actual fact, I don't think we need to call it and start because and start with the UI and presenter
67
00:05:10,860 --> 00:05:13,260
knows that it should get some initial values.
68
00:05:13,290 --> 00:05:19,710
So what we're going to do here in Level Presenter is we're going to register on that observer.
69
00:05:20,130 --> 00:05:25,380
So we're going to look for a level dots on experience changed.
70
00:05:25,680 --> 00:05:31,230
We're going to add a listener which is going to update the UI when the experience changes.
71
00:05:31,350 --> 00:05:38,940
And just to give an initial value to those UI elements, we're going to also call Update UI in Start.
72
00:05:39,030 --> 00:05:44,400
So we'll listen for changes, but we'll also initialize ourselves the first time.
73
00:05:44,580 --> 00:05:46,140
So this is a nice, neat model.
74
00:05:46,140 --> 00:05:49,560
It means that our level no longer even needs a stop method.
75
00:05:49,680 --> 00:05:57,420
You can see here it's now entirely dealing with its own game logic, and it's just calling to observers
76
00:05:57,720 --> 00:06:04,440
when certain relevant events change so things can hook into when the experience changes, when the level
77
00:06:04,440 --> 00:06:06,120
up action takes place.
78
00:06:06,690 --> 00:06:08,620
So that's nice and straightforward.
79
00:06:08,850 --> 00:06:17,310
We now need to set this up over in unity, so we go back into the editor and on the canvas object,
80
00:06:17,310 --> 00:06:21,690
I think might be the natural level up from these UI elements.
81
00:06:21,690 --> 00:06:24,870
I'm going to add a component which is going to be our level presenter.
82
00:06:25,530 --> 00:06:29,760
The level presenter needs hooking up to some different things, so the first thing it needs hooking
83
00:06:29,760 --> 00:06:36,900
up to is the level text needs hooking up to the experience text and the increase experienced button.
84
00:06:36,900 --> 00:06:42,660
So we hook all that up and then we need to hook up to the actual level model script, which is on observe,
85
00:06:42,660 --> 00:06:45,140
for example, so we can just pop that in there.
86
00:06:45,150 --> 00:06:47,730
And now you can see that on the actual observer.
87
00:06:47,730 --> 00:06:51,420
We no longer have all these dirty, horrible references to UI.
88
00:06:51,630 --> 00:06:52,620
That's all gone.
89
00:06:52,800 --> 00:06:58,470
It's now the UI itself, or rather the presenter that is hooked up into the model.
90
00:06:58,770 --> 00:07:03,810
So if we go ahead and just check that everything is still functional and working as we would like it
91
00:07:03,810 --> 00:07:10,560
to, you can see that by gaining experience, I can eventually level up so my button input is working,
92
00:07:10,560 --> 00:07:13,320
my UI presentation is working.
93
00:07:13,560 --> 00:07:16,980
All that remains to be done is to do the same thing for the health bar.
94
00:07:17,190 --> 00:07:23,310
So here are the steps for you to take to make your health and the app you're going to create a health
95
00:07:23,310 --> 00:07:25,300
presenter class MVP class.
96
00:07:25,620 --> 00:07:29,400
You're going to move the logic over from the health module.
97
00:07:29,400 --> 00:07:32,730
Anything that's to do with you, are you going to move into that present class?
98
00:07:33,120 --> 00:07:40,140
You're going to add observers to the module so that the presenter can hook into those observers without
99
00:07:40,140 --> 00:07:42,360
the model knowing anything about the presenter.
100
00:07:42,900 --> 00:07:48,330
And you're going to hook up all of the dependencies in unity, pause the video and have a go.
101
00:07:51,340 --> 00:07:51,890
OK.
102
00:07:51,910 --> 00:07:55,120
Welcome back, so we're going to go in and create the class first of all.
103
00:07:55,120 --> 00:07:59,800
So a new UI file called Health Presenter.
104
00:08:01,410 --> 00:08:05,760
Yes, and we're going to create a lot of behavior within here that we're going to go over to our health
105
00:08:05,760 --> 00:08:12,510
model, we're going to eradicate the using unity engine UI and move it over to our presenter so that
106
00:08:12,510 --> 00:08:14,040
we can see what needs changing.
107
00:08:14,310 --> 00:08:18,690
What needs changing is this health bar image reference that needs to come over to the health presenter.
108
00:08:19,020 --> 00:08:24,720
And like I said before, we also need a serialized field, which I'm going to need the autocomplete
109
00:08:24,720 --> 00:08:24,900
for.
110
00:08:24,900 --> 00:08:31,530
So I'm going to go back into Unity Engine have it's just bumped my auto complete so that I can now do
111
00:08:31,800 --> 00:08:32,610
auto complete this year?
112
00:08:32,610 --> 00:08:37,950
Let's field and I'm going to have a serialized field to the health component, which I'm just going
113
00:08:37,950 --> 00:08:40,030
to call health, says the health model, essentially.
114
00:08:40,440 --> 00:08:44,980
And then we need to have a look at where we've got our update UI.
115
00:08:45,000 --> 00:08:53,130
I'm just going to take the update UI method wholesale over into our health presenter like so we are
116
00:08:53,160 --> 00:08:57,930
then going to needs to cool that in our start method.
117
00:08:57,940 --> 00:09:01,350
So we're going to add start and we get a call update UI in here.
118
00:09:01,950 --> 00:09:06,150
We're going to need to where we've got current health and full health.
119
00:09:06,540 --> 00:09:09,780
This is not currently exposed.
120
00:09:10,230 --> 00:09:16,440
I think we've got we've got get health, but we don't have a get full health from our model, so we
121
00:09:16,440 --> 00:09:17,490
could have that exposed.
122
00:09:17,490 --> 00:09:25,680
We'll have a float, get full health, which is simply going to return the full health variable out
123
00:09:25,680 --> 00:09:26,130
of there.
124
00:09:26,640 --> 00:09:28,800
So now we need to update this code.
125
00:09:28,800 --> 00:09:34,530
So that does health dot get health and divide that by health?
126
00:09:34,530 --> 00:09:40,110
Dot gets full health like so and that's going to achieve the same thing now.
127
00:09:40,110 --> 00:09:47,700
If we go over into our health component, the thing that we need to do is have some sort of notification
128
00:09:47,700 --> 00:09:50,850
method because we can see that we're updating the health.
129
00:09:51,150 --> 00:09:57,510
When we health train, we're updating the health when we reset the health, and that needs to notify
130
00:09:57,810 --> 00:09:59,460
any potential observers.
131
00:09:59,460 --> 00:10:07,740
So we're going to add a public event of type action called on health change.
132
00:10:08,640 --> 00:10:13,470
And we are going to call this where we were previously calling update UI.
133
00:10:13,470 --> 00:10:21,210
So we're going to say if on health change is not equal to null, then we're going to do on health change
134
00:10:21,390 --> 00:10:26,840
parentheses and we're going to do that same thing over in health drain.
135
00:10:26,850 --> 00:10:31,140
So when we change the health value by decreasing it over time.
136
00:10:31,800 --> 00:10:34,680
And that should call to anything observing.
137
00:10:34,680 --> 00:10:36,900
Currently, the health presenter is not observing.
138
00:10:37,200 --> 00:10:39,810
So in start, we do want to set that up.
139
00:10:39,810 --> 00:10:48,270
We want to do a health dot and on health change, we can do a plus equal and add update UI to be called
140
00:10:48,270 --> 00:10:49,230
as an observer.
141
00:10:49,680 --> 00:10:57,330
So now what will happen is the first time on start will get an initial value from the health and then
142
00:10:57,330 --> 00:11:04,200
thereafter we are going to update ourselves when the health system tells us to.
143
00:11:04,620 --> 00:11:10,080
So if we go to check that it's doing the first reset in a week, which is great because stuff is going
144
00:11:10,080 --> 00:11:14,490
to happen after that and get the fully set value for health.
145
00:11:15,270 --> 00:11:24,230
So let's go over into our editor, let things recompile, and we just need to hook everything up now.
146
00:11:24,240 --> 00:11:29,220
So on the canvas, I'm going to add a health present presenter mono behavior and now we need to hook
147
00:11:29,220 --> 00:11:29,490
it up.
148
00:11:29,490 --> 00:11:31,860
So first of all, where is the health image?
149
00:11:31,890 --> 00:11:33,720
Well, it's the one called bar here.
150
00:11:34,410 --> 00:11:39,840
So I'm going to drag that in and then I need to drag in again, the observer example, which has the
151
00:11:39,870 --> 00:11:42,720
health components model on it.
152
00:11:42,780 --> 00:11:49,290
So if we go ahead and play now, hopefully everything should be unchanged and we still getting the decreasing
153
00:11:49,290 --> 00:11:53,100
happening over on a regular basis because we're getting those events come through.
154
00:11:53,100 --> 00:12:00,300
If I add enough experience and it causes us to reset the health that also comes through instantaneously
155
00:12:00,570 --> 00:12:02,160
updates the UI.
156
00:12:02,190 --> 00:12:07,620
So essentially, what we've got from a functionality standpoint is completely unchanged.
157
00:12:08,010 --> 00:12:15,960
But now we've split that into two separate classes one that deals with gameplay, albeit health and
158
00:12:15,970 --> 00:12:22,350
level, and two that represent UI, which is the level presents are in the health presenter.
159
00:12:22,590 --> 00:12:28,850
And we notionally have a third level of abstraction here, which is the view itself.
160
00:12:28,860 --> 00:12:31,470
And that's all handled passively.
161
00:12:31,470 --> 00:12:33,030
Essentially in unity.
162
00:12:33,030 --> 00:12:36,420
There's no code that we're writing that handles the view.
163
00:12:36,630 --> 00:12:41,880
It's all pushed and manipulated by this middleman, which is the presenter.
164
00:12:42,210 --> 00:12:44,490
So hopefully that's made it clearer for you.
165
00:12:44,550 --> 00:12:52,530
What model view controller is, what MVP Model V presenter is and how it's relevant to games and your
166
00:12:52,530 --> 00:12:54,600
implementations in Unity.
167
00:12:54,750 --> 00:12:55,860
I'll see you in the next lecture.
17782
Can't find what you're looking for?
Get subtitles in any language from opensubtitles.com, and translate them here.