Would you like to inspect the original subtitles? These are the user uploaded subtitles that are being translated:
1
00:00:04,640 --> 00:00:10,600
So let us imagine for a second that we are writing a special abilities system, and in this special
2
00:00:10,610 --> 00:00:17,090
ability system, you could have one of a number of special abilities equipped and that could change
3
00:00:17,090 --> 00:00:18,080
it while you're playing.
4
00:00:18,140 --> 00:00:24,170
You could run into fireball power up and you could get fireball special ability, for example.
5
00:00:24,260 --> 00:00:26,000
Now, very naive and probably not.
6
00:00:26,000 --> 00:00:31,670
The best way of doing this would be to have an ability run out on a behavior that's not the problem
7
00:00:31,670 --> 00:00:37,070
here, but then configuring the particular ability that you have using an inner.
8
00:00:37,080 --> 00:00:43,370
So here, for example, I've got an ability in them and it could be the fireball rage or heal that is
9
00:00:43,370 --> 00:00:44,870
equipped at any given time.
10
00:00:44,870 --> 00:00:51,440
And we can imagine that this could happen through power ups or running into different colliders, that
11
00:00:51,440 --> 00:00:51,890
sort of thing.
12
00:00:51,900 --> 00:00:57,950
But what is clearly visible is that if we had a set for this, you could set the ability at runtime
13
00:00:57,950 --> 00:01:04,760
and then when the use ability public method is called, maybe by hitting a spacebar or clicking a mouse
14
00:01:04,760 --> 00:01:09,060
button or something like that, then a switch is triggered here.
15
00:01:09,680 --> 00:01:16,310
And depending on which enum we've got selected, a different behavior happens down below.
16
00:01:17,240 --> 00:01:22,160
Now, the problem with this is that every time I want to add a new ability, I need to come into this
17
00:01:22,160 --> 00:01:22,700
class.
18
00:01:23,150 --> 00:01:26,000
If these abilities are more complicated, which they should be.
19
00:01:26,300 --> 00:01:32,210
Then I'm going to have to add a lot of code into here, and it doesn't separate any of that out.
20
00:01:32,630 --> 00:01:42,620
So the better way for us to implement abilities is for ability runner to have an ability field, still
21
00:01:42,650 --> 00:01:43,940
a current ability field.
22
00:01:44,210 --> 00:01:51,380
But instead, this ability points to an interface, an ability or an AI ability interface, which has
23
00:01:51,380 --> 00:01:56,450
a use method and because it's an interface, didn't actually have any code in that use method.
24
00:01:56,780 --> 00:02:01,550
It's just defining the contract for what availability should look like.
25
00:02:02,060 --> 00:02:09,770
So then the ability run up word when use ability it would call use on the currently set ability, then
26
00:02:10,400 --> 00:02:18,170
we could have a fireball ability which inherits from the ability interface and actually concretely implements
27
00:02:18,170 --> 00:02:19,040
its use method.
28
00:02:19,400 --> 00:02:27,500
And we could have a rage ability, which derives again from the ability interface and implements its
29
00:02:27,500 --> 00:02:28,220
use method.
30
00:02:28,940 --> 00:02:36,620
Now, if I were to go and change the names here, what we've just gone ahead and implemented is the
31
00:02:36,620 --> 00:02:37,760
strategy pattern.
32
00:02:37,820 --> 00:02:48,470
So if we swap out ability for strategy and we swap out use for algorithm, then it is exactly a match
33
00:02:48,470 --> 00:02:49,760
for the strategy pattern.
34
00:02:49,760 --> 00:02:51,920
And this is what I mean about Golden Handler syndrome.
35
00:02:52,130 --> 00:02:56,480
If we'd been looking to fit the strategy pattern into here, that would be one thing.
36
00:02:56,690 --> 00:03:04,160
But when you've got a problem and you go ahead and solve it with a sensible, object oriented approach,
37
00:03:04,430 --> 00:03:09,440
you often find that you have stumbled across a pattern that you didn't realize.
38
00:03:10,130 --> 00:03:15,410
So let's try and implement this, and we're going to factor out some of it, and I'm going to leave
39
00:03:15,470 --> 00:03:17,720
some of it for you to do in a second.
40
00:03:17,750 --> 00:03:22,280
So the first thing to do is I'm going to comment out this switch statement because we no longer need
41
00:03:22,280 --> 00:03:27,080
that, but it will be a reference for what functionality we want to take elsewhere.
42
00:03:27,770 --> 00:03:31,370
Current ability is currently pointing to this enum.
43
00:03:31,760 --> 00:03:33,050
Let's switch that up.
44
00:03:33,320 --> 00:03:38,630
So instead, and I'm going to do this all within the same file for simplicity's sake, but obviously
45
00:03:38,630 --> 00:03:41,180
in reality, we would create different files here.
46
00:03:41,870 --> 00:03:44,150
I'm going to create a public interface.
47
00:03:45,600 --> 00:03:46,880
Of type, I.
48
00:03:46,900 --> 00:03:52,780
Ability and this is just the C-sharp thing that we prefix interfaces with ability depending on the language
49
00:03:52,780 --> 00:03:55,660
you're using, that might be different now.
50
00:03:56,410 --> 00:04:00,340
Then we want to define a use method in here.
51
00:04:00,340 --> 00:04:02,530
So that's just for sake of argument.
52
00:04:02,530 --> 00:04:05,770
Say it's a void method use that takes no parameters.
53
00:04:06,310 --> 00:04:09,280
And it's worth noting that you don't have to put public here.
54
00:04:09,280 --> 00:04:14,520
In fact, it's an error to put a public in the interface because by definition, there's nothing private
55
00:04:14,530 --> 00:04:15,250
in an interface.
56
00:04:15,790 --> 00:04:18,250
Everything is public, so there's no point.
57
00:04:18,820 --> 00:04:25,030
So then, instead of using the Enum, we're going to use our AI ability interface down here.
58
00:04:25,720 --> 00:04:27,880
And that's going to be the current ability.
59
00:04:28,210 --> 00:04:34,390
Obviously, we can't instantiate this to anything because we need some kind of concrete class.
60
00:04:34,600 --> 00:04:43,400
So I'm going to go ahead and create a public class called rage ability that's going to inherit from
61
00:04:43,400 --> 00:04:44,020
my ability.
62
00:04:44,030 --> 00:04:45,580
In fact, not inheriting anything.
63
00:04:45,580 --> 00:04:51,040
It is implementing AI ability and for it to properly implement liability.
64
00:04:51,040 --> 00:04:55,570
It needs to have a use method so you can automatically do this with interface.
65
00:04:55,570 --> 00:04:59,060
By doing control dots and hitting implement interface.
66
00:04:59,080 --> 00:05:05,440
You can see it goes ahead and creates a public void use method that matches the signature in the interface.
67
00:05:06,190 --> 00:05:07,870
So now we've got a rage ability.
68
00:05:08,170 --> 00:05:12,330
We can use it anywhere where we take an AI ability type.
69
00:05:12,340 --> 00:05:15,160
So we have this AI ability, current ability field.
70
00:05:15,160 --> 00:05:23,770
I could go ahead and do new rage ability like so and that's going to give it an initial value then over.
71
00:05:24,190 --> 00:05:29,080
We want to actually put some ability into that rage.
72
00:05:29,080 --> 00:05:32,800
So I'm going to take this debug statement that we were previously using.
73
00:05:33,130 --> 00:05:36,740
Cut it out here and put that into the use method.
74
00:05:36,910 --> 00:05:46,060
So now that rage ability can be simply substituted in to our current ability and whenever we call usability,
75
00:05:46,060 --> 00:05:50,420
we're going to do current ability, dot use like so.
76
00:05:50,470 --> 00:05:56,530
And you may want to wrap this with some checks to see whether the ability is actually set to null because
77
00:05:56,530 --> 00:06:02,710
if it's set to null, obviously there's no no implementation for use and it will cause an error depending
78
00:06:02,710 --> 00:06:08,080
on whether you can ever have a situation where there is no ability enabled in your ability runner.
79
00:06:08,170 --> 00:06:09,430
So there's a challenge to you.
80
00:06:09,430 --> 00:06:17,950
I want you to go ahead and implement an AI ability class subclass for Ray, for Fiable now and for he'll
81
00:06:18,640 --> 00:06:23,860
pretty much following in the steps that we used for the rage, ability pause video and a half ago.
82
00:06:27,910 --> 00:06:29,050
OK, welcome back.
83
00:06:29,080 --> 00:06:32,550
So this should be reasonably straightforward, almost a copy and paste job.
84
00:06:32,790 --> 00:06:41,130
We're going to have a public class called Heal Ability, which basically implements the liability interface
85
00:06:41,130 --> 00:06:41,580
again.
86
00:06:41,880 --> 00:06:47,010
It's going to we can use control to go ahead and implement that interface automatically for us.
87
00:06:47,340 --> 00:06:59,160
We can take the debug log for heal and stick it in use and then we can rinse and repeat for public class.
88
00:06:59,820 --> 00:07:02,150
And this time we wanted, what's the other one?
89
00:07:02,160 --> 00:07:09,900
I have the fire ball ability and the fire ball ability could also implement the eye ability.
90
00:07:09,900 --> 00:07:14,130
In fact, it must, and that we can put the different code.
91
00:07:15,240 --> 00:07:21,600
Now on this very simplistic example, it doesn't seem like we've necessarily gained very much.
92
00:07:22,020 --> 00:07:29,700
But what's useful to know is that we one thing we could do with ability is we could pass in the ability
93
00:07:29,700 --> 00:07:36,360
runa or we could pass in the current game object or anything that could link these abilities back to
94
00:07:36,360 --> 00:07:36,900
the world.
95
00:07:37,020 --> 00:07:40,680
So in Unity, for example, the game object might be very useful.
96
00:07:40,890 --> 00:07:49,200
So with in use, we could pass the game object should be the current game object like so.
97
00:07:49,620 --> 00:07:53,950
Now, obviously, this has gone ahead and changed the signature for all the classes.
98
00:07:53,970 --> 00:08:01,470
So that's going to cause a compile error so we can go through and pass that game object in or just go
99
00:08:01,470 --> 00:08:05,580
and change the code so that it has that signature on all of the abilities.
100
00:08:06,540 --> 00:08:12,930
And we can pass in the current game object in usability so we can just passing game object like so.
101
00:08:13,290 --> 00:08:16,230
So this means that these classes are now linked back to the world.
102
00:08:16,230 --> 00:08:21,510
So if you wanted to launch particle effects and play sounds and all that sort of stuff, we can do that
103
00:08:21,510 --> 00:08:22,830
we've got a place to spawn stuff.
104
00:08:23,160 --> 00:08:25,020
We've got a reference to our world.
105
00:08:25,710 --> 00:08:30,750
And now you can see that we could have very complicated functionality going on within each of these
106
00:08:30,750 --> 00:08:31,290
classes.
107
00:08:31,590 --> 00:08:36,929
And if we need to change anything about the fire ball ability, we only need to do it there.
108
00:08:36,929 --> 00:08:39,740
We don't need to go and change this ability runner.
109
00:08:39,750 --> 00:08:42,870
In fact, the ability to run a stay is very, very simple.
110
00:08:43,080 --> 00:08:48,570
One more important thing to note here is that because we're only implementing an interface, we actually
111
00:08:48,570 --> 00:08:54,120
have the ability to have these abilities be anything we like.
112
00:08:54,300 --> 00:09:01,320
So at the moment, they are pure C-sharp classes, but the rage ability could actually be a mono behavior
113
00:09:01,590 --> 00:09:08,070
like so and we could have the heel ability be a scriptural object, and that opens up a whole world
114
00:09:08,070 --> 00:09:08,970
of possibilities.
115
00:09:08,970 --> 00:09:11,460
That means the rage ability could be a prefab.
116
00:09:11,460 --> 00:09:13,410
The heal ability could be a spiritual object.
117
00:09:13,680 --> 00:09:19,620
And as long as you have a way of injecting that into your ability runner, as long as you maybe have
118
00:09:19,620 --> 00:09:27,840
an array of sterilized fields or whatever goes, setting that ability is able to deal with this, then
119
00:09:27,840 --> 00:09:33,180
you could do this in a number of ways, and it doesn't matter what they inherit from.
120
00:09:33,180 --> 00:09:36,390
It doesn't matter how they do the job as long as they implement, not you.
121
00:09:36,390 --> 00:09:43,620
The eye ability, that ability to use the ability, then they can be anything you want them to be,
122
00:09:43,620 --> 00:09:45,390
and that can be immensely valuable.
123
00:09:45,390 --> 00:09:50,400
If you want a configurable ability system, you might make your ability, scriptural objects, mono
124
00:09:50,400 --> 00:09:53,790
behaviors or pure C-sharp classes, whatever you want.
125
00:09:54,330 --> 00:09:59,010
If you're interested in this sort of stuff, then the RPG series on a special abilities.
126
00:09:59,190 --> 00:10:06,060
The last episode in that series is all about creating ability systems, and we go into much more depth,
127
00:10:06,060 --> 00:10:10,290
obviously, that I can do here in how to implement that sort of thing.
128
00:10:10,740 --> 00:10:16,200
But for now, in the next lecture, we're going to go into some more depth on this mini ability system
129
00:10:16,470 --> 00:10:22,140
into how we can use a different design pattern to make this even more flexible.
130
00:10:22,290 --> 00:10:22,890
I'll see you that.
14145
Can't find what you're looking for?
Get subtitles in any language from opensubtitles.com, and translate them here.