WEBVTT

00:06.990 --> 00:07.860
Welcome.

00:07.860 --> 00:12.810
In this video, we're going to make an actor that can change our attributes.

00:12.960 --> 00:19.350
We'll often want some sort of object in our world that we can pick up that will affect our attributes

00:19.350 --> 00:20.490
in some way.

00:20.490 --> 00:27.480
So I'd like to have an actor that's sort of generic all purpose that we can use that has the inherent

00:27.480 --> 00:29.510
capability of changing attributes.

00:29.520 --> 00:35.610
Now we already know that the preferred way to change an attribute is through a gameplay effect, but

00:35.610 --> 00:39.810
we haven't learned how to create and use gameplay effects just yet.

00:39.810 --> 00:46.050
So we're going to make an actor that will change an attribute directly and we'll see the limitations

00:46.050 --> 00:53.550
of doing it that way and we'll create a sort of to do basically add a comment that says we plan on changing

00:53.550 --> 00:57.210
our system to use gameplay effects in the near future.

00:57.210 --> 00:59.730
So let's make a new actor class.

00:59.730 --> 01:01.920
I'm going to go ahead and launch the editor.

01:02.710 --> 01:05.110
And we'll make a new C plus plus class.

01:05.110 --> 01:11.650
So I'm going to go into C plus plus classes, Aura public and right click and make a new C plus plus

01:11.650 --> 01:12.190
class.

01:12.190 --> 01:14.890
And this is going to simply be an actor.

01:14.890 --> 01:20.500
I'm going to click next and I'll put this in its own folder called Actor.

01:20.530 --> 01:25.480
Now, this will be a sort of generic class that will apply some sort of effect.

01:25.480 --> 01:30.400
So I'm going to call this aura effect actor and create the class.

01:32.050 --> 01:37.630
I'll go ahead and close the editor and open up my new actor here in Writer.

01:37.630 --> 01:40.540
So here's aura effect actor wkRP.

01:40.900 --> 01:44.260
And I'll go ahead and open up the header file as well.

01:44.470 --> 01:45.520
Here we go.

01:45.520 --> 01:47.980
And I'll drag them over to the left here.

01:48.250 --> 01:52.100
Now, aura effect actor is going to be pretty simple.

01:52.120 --> 01:58.300
We'll make this much more versatile in the future, but for now I just want to be able to overlap with

01:58.300 --> 02:03.830
or affect actor and apply some kind of attribute change.

02:03.850 --> 02:07.600
So for now I'm going to remove the tick function.

02:09.230 --> 02:16.070
I'm going to remove the comments that we get here by default and in the CPP file, I'll remove the tick

02:16.070 --> 02:19.580
function here and remove these comments as well.

02:21.570 --> 02:26.100
And because we don't need to tick, I'm going to set this to false primary actor.

02:26.100 --> 02:27.960
Tick B can never tick.

02:27.990 --> 02:31.410
No ticking behavior, at least so far.

02:31.410 --> 02:35.220
Now, aura effect actor needs some kind of overlap volume.

02:35.220 --> 02:40.680
I'm going to opt for a sphere and this will be a private variable.

02:40.680 --> 02:47.850
So I'll make a private section and add a T object pointer of type use sphere component.

02:47.880 --> 02:51.030
We'll go ahead and add a forward declaration for that.

02:51.060 --> 02:59.790
Thanks to writer for the shorthand and this will be called simply Sphere and I'll give it a new property

02:59.790 --> 03:01.380
with visible anywhere.

03:01.980 --> 03:03.930
And that's all we need for now.

03:03.930 --> 03:06.270
Let's go ahead and construct it.

03:06.270 --> 03:10.020
So here in the constructor we'll say sphere equals.

03:10.110 --> 03:18.600
I'll use create default Subobject specifying use sphere component and thanks writer for the auto include

03:18.600 --> 03:26.680
there and the native name will be simply sphere and we can make the sphere the root component or we

03:26.680 --> 03:29.350
can attach it to the root.

03:29.380 --> 03:30.880
Either one is fine.

03:30.880 --> 03:36.640
I think what I'd like to do is have a static mesh as the root and attach the sphere to it.

03:36.640 --> 03:41.410
So we can go back to the header file and we can add a static mesh component.

03:41.530 --> 03:51.670
This can be a T object pointer of type use, static mesh component and we'll call this simply mesh and

03:51.670 --> 03:57.760
make this also visible anywhere so we can go back and construct our mesh.

03:57.760 --> 04:01.150
Since I'd like to make the mesh the root, I'm going to put it above the sphere.

04:01.150 --> 04:09.070
So I'll say mesh equals and we'll use create default subobject with use static mesh component this time

04:09.070 --> 04:14.620
and call this simply mesh and we'll set the mesh as the root.

04:14.620 --> 04:20.800
So we'll say set root component mesh and we'll attach the sphere to the root.

04:20.800 --> 04:25.360
So we'll say sphere setup attachment, get root component.

04:25.360 --> 04:28.780
That way, if the mesh moves, the sphere moves with it.

04:28.900 --> 04:37.150
Now we just need a overlap function to call when Sphere overlaps with some other actor and we'll go

04:37.150 --> 04:40.600
ahead and make an end overlap function as well.

04:40.600 --> 04:43.030
And this is all stuff you should be familiar with.

04:43.180 --> 04:46.930
We'll make the overlap functions and they can be public.

04:46.930 --> 04:50.200
We're going to make a virtual function.

04:50.440 --> 04:51.550
It's going to be void.

04:51.550 --> 04:54.220
We'll call it simply on overlap.

04:55.150 --> 05:02.980
Now, the on overlap function signature needs to have a number of input parameters to make this function

05:02.980 --> 05:11.200
bindable to on component begin overlap on the sphere and I'll quickly show you how to figure out what

05:11.200 --> 05:12.970
those input parameters should be.

05:12.970 --> 05:14.230
But first we're going to add them.

05:14.230 --> 05:16.660
We're going to say you primitive component.

05:16.660 --> 05:18.070
That's the first one.

05:18.580 --> 05:23.310
That's a pointer called overlapped component.

05:23.310 --> 05:29.100
We have an a actor called other actor, another you primitive component.

05:30.960 --> 05:35.790
Called other comp and in 32 called other body index.

05:38.260 --> 05:42.970
A bool called B from sweep and a const F hit result.

05:45.470 --> 05:47.750
Reference called sweep result.

05:49.400 --> 05:51.950
And this must be a new function.

05:52.190 --> 05:54.050
So we'll add the new function there.

05:54.050 --> 05:58.220
And this is a function we can bind to on component began overlap.

05:58.220 --> 06:00.170
So we'll generate the function.

06:01.360 --> 06:09.040
Here's the definition and we'll bind this to on component began overlap on our sphere which we must

06:09.040 --> 06:10.240
do in begin play.

06:10.450 --> 06:14.770
So we're going to say sphere on component begin overlap.

06:17.000 --> 06:22.520
Dot add dynamic as this is a dynamic multicast delegate.

06:22.550 --> 06:29.570
We pass in the user object and the callback function which will be the address of a or effect actor

06:29.600 --> 06:30.980
on overlap.

06:31.550 --> 06:39.770
So this is the basic way to have a callback function fired off in response to something overlapping

06:39.770 --> 06:41.410
with our sphere component.

06:41.420 --> 06:45.980
And I mentioned I'd tell you how I knew this function signature.

06:45.980 --> 06:51.650
If you don't know how to figure that out on some kind of delegate, you can right click and go to the

06:51.650 --> 06:58.040
definition of that delegate we see here on component began overlap belongs to primitive component and

06:58.040 --> 06:59.360
this is its type.

06:59.390 --> 07:02.450
We can go to the definition of this.

07:03.510 --> 07:11.400
And we see that it's created here with declared dynamic multicast, sparse delegate and this delegate

07:11.430 --> 07:17.340
of type F component began overlap signature is defined using this macro.

07:17.550 --> 07:25.380
And here we see the input parameters required for any callback that will be bound to this delegate.

07:25.530 --> 07:31.740
And here's F component end overlap signature the delegate for end overlap events.

07:31.740 --> 07:37.890
If we want to bind a function to that, then here's the list of input parameters that a callback must

07:37.890 --> 07:39.960
have to bind to.

07:39.960 --> 07:46.290
This type of delegate and primitive component has one called on component end overlap.

07:46.290 --> 07:52.620
So we can copy these parameters and we can make our end overlap function here in effect.

07:52.620 --> 07:57.090
Actor So we're going to make a virtual void function called end overlap.

07:57.420 --> 08:00.150
And I'm going to paste in those input parameters.

08:00.150 --> 08:09.340
Now in the declared delegate macro, the type is separated from the variable name and the first two

08:09.340 --> 08:14.410
here are you primitive component and on component end overlap.

08:14.410 --> 08:17.830
That's going to be the name of the delegate itself.

08:17.830 --> 08:19.960
We're going to remove those two.

08:19.990 --> 08:24.430
The syntax may change from version to version in older versions of the engine.

08:24.430 --> 08:30.100
We didn't have these first two there, but the function signature begins with a primitive component

08:30.100 --> 08:32.250
pointer called overlapped component.

08:32.260 --> 08:34.960
So removing the comma between type and name.

08:34.960 --> 08:35.470
There.

08:35.500 --> 08:39.580
For each of these, we can see what that signature should be.

08:39.580 --> 08:46.120
So this is kind of a little trick that you can use if you want to know the function signature for any

08:46.120 --> 08:48.370
function that can be bound to a given delegate.

08:48.370 --> 08:53.080
And throughout this course, we're going to be making lots of our own custom delegates.

08:53.080 --> 08:58.870
So we'll be seeing more and more of the inner workings of how these relationships work between delegates

08:58.870 --> 09:00.220
and callbacks.

09:00.220 --> 09:09.550
But for now, we're just binding a pair of callbacks to delegates on the primitive component type from

09:09.550 --> 09:11.980
which sphere is derived.

09:11.980 --> 09:19.180
So let's go ahead and generate the end overlap function definition and we'll go ahead and bind end overlap

09:19.180 --> 09:21.310
to the sphere.

09:21.550 --> 09:26.320
So we'll say sphere on component end overlap.

09:26.650 --> 09:33.310
We can hover over it and see that this is a component end overlap signature delegate and we can bind

09:33.310 --> 09:34.840
with add dynamic.

09:34.990 --> 09:39.760
We can bind to this object and it's going to be the callback.

09:40.530 --> 09:44.430
Aura effect actor end overlap like so.

09:44.820 --> 09:52.350
So for actors that have overlap volumes that you want to trigger off some kind of function call in response

09:52.350 --> 09:53.240
to overlaps.

09:53.250 --> 09:55.530
This is all very much boilerplate, right?

09:55.530 --> 09:58.680
We call this boilerplate because it has to be done.

09:58.680 --> 10:01.440
If you want an actor that can overlap something.

10:01.770 --> 10:10.380
Now for actually defining what to do when we overlap, that's what we really want to figure out here

10:10.380 --> 10:13.050
is what do we do when we overlap with something?

10:13.050 --> 10:21.240
Now we'd like to change the value of one of the attributes in the attribute set for Aura.

10:21.240 --> 10:27.420
But we know that to do that, we should be really applying gameplay effects and that's why we call this

10:27.420 --> 10:28.800
effect actor.

10:28.800 --> 10:37.650
But until we learn how to do that, we're just going to change a value such as the health attribute

10:37.680 --> 10:45.790
on Aura, and that will give us the opportunity to learn how we can access auras, attribute set and

10:45.790 --> 10:46.570
her attributes.

10:46.570 --> 10:53.050
But we'll also learn how this is a very limited approach that restricts us in a lot of ways.

10:53.050 --> 10:55.780
We don't have a lot of freedom and flexibility.

10:55.780 --> 11:04.780
So first let's learn how we can access the other actors ability system component on overlap since we

11:04.780 --> 11:11.530
have access to the other actor, the actor that overlapped with this particular sphere component, We

11:11.530 --> 11:15.670
can see if that other actor has an ability system component.

11:15.700 --> 11:23.260
Remember in the owner actors where we constructed our ability system component, we made sure to implement

11:23.260 --> 11:26.680
a specific interface related to the ability system.

11:26.680 --> 11:34.660
If we go to say, the player folder in the public folder here or a player state, we see that we made

11:34.660 --> 11:42.070
sure the Aura player state is derived from AI ability system interface and that interface has a pure

11:42.100 --> 11:45.610
virtual function get ability system component.

11:45.640 --> 11:50.980
Now this is very nice because we can take any actor and see if it implements this interface.

11:50.980 --> 11:56.650
And if it does, we can get the ability system component that belongs to that actor.

11:56.650 --> 12:02.770
So we really don't have to care what type that actor is, whether it's a character, a pawn or just

12:02.770 --> 12:03.670
an actor.

12:04.090 --> 12:09.010
If it implements the interface, we can call get ability system component on it.

12:09.010 --> 12:15.760
So here in on Overlap, what I'd like to do is take the other actor and cast it to an AI ability system

12:15.760 --> 12:16.540
interface.

12:16.540 --> 12:19.720
So I'm going to make a local AI ability system.

12:20.800 --> 12:27.840
Interface pointer called ASC interface for lack of a better name.

12:27.850 --> 12:32.050
And I'm going to cast to I ability system interface.

12:32.950 --> 12:35.170
The other actor itself.

12:36.040 --> 12:38.320
And I can wrap this in an if statement.

12:38.320 --> 12:47.080
I can say if this doesn't return a null pointer, then ASC interface will exist within the scope of

12:47.080 --> 12:48.280
this if statement.

12:48.280 --> 12:55.150
And what I can do here since I have the interface is I can find the attribute set.

12:55.180 --> 13:03.430
Now I know that aura attribute set has a health attribute, so I can find an attribute set on this ability

13:03.460 --> 13:07.000
system component of that type if it has one.

13:07.150 --> 13:10.690
Now this is a very limited approach.

13:10.720 --> 13:16.960
Again, once we use gameplay effects, we won't have to care what the type of the attribute set is.

13:16.990 --> 13:21.790
If we want to change some sort of value of an attribute.

13:21.790 --> 13:27.550
But for now, until we learn better ways to do it, we're going to learn how to get that attribute set

13:27.550 --> 13:29.320
from the ability system.

13:29.440 --> 13:35.110
So what we do first is we take the interface which we know implements.

13:35.800 --> 13:39.520
The pure virtual function get ability system component.

13:39.550 --> 13:44.560
Now we can assume that that ability system component will be a valid pointer.

13:44.560 --> 13:50.140
So far in our game we haven't implemented this function on any actors.

13:50.140 --> 13:53.440
That should return a null pointer if we call it.

13:53.440 --> 14:00.700
So I'm not going to bother checking it to see if it's null and from the ability system component I'm

14:00.700 --> 14:03.610
going to call get attribute set.

14:03.790 --> 14:11.440
Now get attribute set is a function that requires a subclass of based on you attribute set.

14:11.470 --> 14:19.270
A subclass of is a new class that we can specify so that the ability system component knows which type

14:19.270 --> 14:22.060
of attribute set to look for if it has one.

14:22.060 --> 14:27.820
So we want to search for you or a attribute set.

14:27.850 --> 14:36.530
That's the class of the attribute set so we can use you or a attribute set static class which will satisfy

14:36.530 --> 14:39.260
this input of type T subclass of.

14:39.620 --> 14:46.940
So this whole expression here is going to return an object of type you attribute set.

14:46.970 --> 14:54.230
So because this returns a you attribute set we are going to want to cast to you or a attribute set.

14:54.380 --> 14:56.360
So I'm going to wrap this all in a cast.

14:56.360 --> 15:04.400
We're going to say cast to you or a attribute set and we'll wrap this up and we can store all of this

15:04.430 --> 15:11.780
in a local you or attribute set pointer called ora attribute set.

15:11.900 --> 15:19.400
And this has to be const because get attribute set returns a const you attribute set.

15:19.400 --> 15:21.620
So we'll add const to this.

15:21.620 --> 15:27.080
And now we have the other actors ora attribute set if it has one.

15:27.080 --> 15:33.800
Now in our game, all of our actors that implement the ability system interface have an Ora attribute

15:33.800 --> 15:34.490
set.

15:34.490 --> 15:38.900
So we know that this should be a valid pointer.

15:38.900 --> 15:41.990
In this case, I'm not going to bother checking if that is null.

15:41.990 --> 15:47.000
I'm just going to take Ora attribute set and we're going to do something.

15:47.000 --> 15:50.900
Now notice we have access to health mana, get health, get mana.

15:50.900 --> 15:58.010
We have these attributes which are public and those attribute accessors thanks to the boilerplate attribute

15:58.010 --> 16:06.260
accessors macro so we can set these values I'm going to call set health and set health requires a float.

16:06.290 --> 16:14.120
Well, I can get the Ora attribute set and call get health and I can add some value.

16:14.120 --> 16:18.950
I'm just going to hardcode a value, say 25.5.

16:19.070 --> 16:25.460
Now we see the red squiggles here because, well, this is a const you ora attribute set.

16:25.460 --> 16:31.000
So we can't really change things if it's a const pointer and that's for our protection.

16:31.010 --> 16:35.090
This is something that the ability system enforces.

16:35.090 --> 16:39.610
We shouldn't be setting the health directly on the Ora attribute set like this.

16:39.640 --> 16:47.380
The Ora attribute set should either set its own attribute values or have those attributes changed in

16:47.380 --> 16:49.320
response to gameplay effects.

16:49.330 --> 16:52.450
So already we're doing something that we shouldn't be.

16:52.450 --> 17:00.220
But since this is for learning purposes only, before we fix this up to have a better design, we're

17:00.220 --> 17:05.440
going to break the rules a bit just so we can set that health value and see it change.

17:05.560 --> 17:13.000
So I'm going to go ahead and give myself a semicolon here that I was missing for this line and ora attribute

17:13.000 --> 17:20.810
set since it's const, well, I'm going to cast away the const ness of Ora attribute set.

17:20.840 --> 17:24.070
Now this is kind of a big no no in programming.

17:24.070 --> 17:29.710
It's not something that you want to be in the habit of doing, but we're going to do this with a big

17:29.710 --> 17:33.040
fat to do, to change this to a better system.

17:33.040 --> 17:42.850
So before I break the rules, I'm going to add a to do comment here that says change this to apply a

17:42.850 --> 17:50.980
gameplay effect for now using const cast as a hack.

17:50.980 --> 17:57.580
So we got this big fat comment telling us that we're doing something we shouldn't be doing and that

17:57.580 --> 17:59.350
we have a to do to change it.

17:59.350 --> 18:07.660
So what we're going to do is create a U or a attribute set and set it equal to the result of a const

18:07.690 --> 18:13.360
cast where const casting to type u or attribute set.

18:13.360 --> 18:20.920
And because we're using const cast, we need the asterisk here and what we're casting is ora attribute

18:20.920 --> 18:32.320
set and we're going to call this mutable ora attribute set and we're going to use mutable ora attribute

18:32.320 --> 18:34.420
set to call set health.

18:34.420 --> 18:35.230
So.

18:35.360 --> 18:36.940
We have a const pointer.

18:36.950 --> 18:43.640
You're not supposed to change const pointers, but if you want to break that rule, we have the power

18:43.640 --> 18:45.380
in C plus plus to do that.

18:45.380 --> 18:49.220
This is something you should use extreme caution with.

18:49.250 --> 18:54.620
All we're doing is breaking encapsulation here and throughout this course we're going to make sure to

18:54.620 --> 18:58.880
maintain proper encapsulation and good coding practices.

18:58.880 --> 19:06.260
But as we would like to simply see the value change, we're going to cast away the consciousness of

19:06.260 --> 19:08.720
this pointer so that we can mutate it.

19:08.720 --> 19:15.140
And of course, once we learn about gameplay effects, which is going to be very soon, we're going

19:15.140 --> 19:21.170
to instead have this function, apply a gameplay effect and we'll see the benefits of that.

19:21.170 --> 19:28.190
So we now have a function for on overlap that will take the health on the attribute set of the actor

19:28.190 --> 19:35.300
that overlapped with it and set it equal to its own health plus 25 and we won't bother with an end overlap

19:35.400 --> 19:36.810
implementation just yet.

19:36.810 --> 19:43.770
All we're going to do here is if we do this, we'll go ahead and destroy the effect actor itself.

19:43.770 --> 19:50.100
So we're just going to call destroy here and now we just want to test this out and overlap with it in

19:50.100 --> 19:53.280
the world and see our health value change.

19:53.800 --> 19:55.760
And that's going to be your quest.

19:55.780 --> 19:58.240
I would like you to create a health potion.

19:58.360 --> 20:02.620
So create a blueprint based on or an effect actor.

20:02.650 --> 20:08.350
You can call it BP Health potion, if you like, and set its static mesh.

20:08.380 --> 20:15.610
Look for the potion bottle static mesh in our assets folder and you can set that and then test the attribute

20:15.610 --> 20:16.500
changes.

20:16.510 --> 20:21.430
Place one in the world, overlap with it and with show debug ability system.

20:21.460 --> 20:24.060
See if you can see that health value change.

20:24.070 --> 20:27.700
So pause the video and conquer this quest now.

20:30.830 --> 20:31.250
Okay.

20:31.250 --> 20:34.520
I'd like to make a blueprint, so I'm going to go ahead and run this.

20:34.520 --> 20:36.350
I'll go ahead and run in debug mode.

20:37.070 --> 20:42.770
And here in the editor, I'm going to go to my blueprints folder and make a new folder here.

20:42.980 --> 20:45.140
I'll go ahead and call this actor.

20:45.170 --> 20:52.700
So we'll place our actors in here and I'll make a new blueprint class and I'll search for aura effect

20:52.700 --> 20:55.430
actor and choose that.

20:55.430 --> 20:58.970
And this will be called BP Health Potion.

21:00.410 --> 21:04.130
And I can open this and I can set the mesh.

21:04.130 --> 21:06.680
I'm going to search for potion bottle.

21:06.680 --> 21:07.730
Here it is.

21:07.730 --> 21:12.530
And there's my potion bottle and I can see that it looks a bit too big.

21:12.530 --> 21:15.020
I'm going to drag one into the world and see how big.

21:15.020 --> 21:16.880
Yes, it is too big.

21:16.880 --> 21:19.940
So I'm just going to scale it down here.

21:19.940 --> 21:24.620
I'm going to multiply the mesh by 0.2 for the scale.

21:24.740 --> 21:26.840
Now that's of course going to scale the sphere down.

21:26.840 --> 21:31.220
So I just need to increase that sphere radius there.

21:31.310 --> 21:36.170
And now that I have a health potion, I can test this out in the world.

21:36.170 --> 21:41.280
I'm going to save all first and press play and hitting the tilde key.

21:41.280 --> 21:50.940
I can type show debug ability system to see the value of my health and if I run up to the potion, I

21:50.940 --> 21:53.990
pick it up and my health is now 125.

21:54.000 --> 21:59.370
So our health potion is increasing our health by 25 as expected.

21:59.400 --> 22:00.450
Perfect.

22:00.690 --> 22:08.220
So we now know how we can access the ability system for any actor and we can access the attribute set

22:08.250 --> 22:11.310
of an actor with get attribute set.

22:11.310 --> 22:18.360
If we pass in the subclass of or the U class for the type of attribute set we'd like to find on that

22:18.360 --> 22:25.230
ability system component and get attribute set returns a const pointer to that attribute set.

22:25.230 --> 22:31.860
And we learned that we could sort of bludgeon our way past that Constness by casting it away with const

22:31.890 --> 22:32.580
cast.

22:32.610 --> 22:39.660
Now you should know that const cast is not something you want to use as a matter of habit.

22:39.720 --> 22:46.500
It's something that you can use if you don't quite know yet how you're going to do what you want to

22:46.500 --> 22:50.580
do, but you're trying to figure out ways to make things work.

22:50.610 --> 22:57.420
It's one of those ways that you can break the rules to get things working, but seeing this in your

22:57.420 --> 23:05.130
code should be a reason to sit and kind of try to think of a different solution that can allow you to

23:05.130 --> 23:09.060
not violate the consciousness of your code base.

23:09.060 --> 23:18.720
And in our case, we made a very blaring comment to tell us that we do plan on removing the requirement

23:18.720 --> 23:19.650
to const cast.

23:19.650 --> 23:22.320
In fact, that's not really the biggest problem here.

23:22.320 --> 23:27.930
The biggest problem is that our aura effect actor is very, very specific.

23:27.930 --> 23:31.050
It changes the health by 25.

23:31.080 --> 23:38.310
Something like effect actor should be able to apply any effect to any attribute in any number of ways.

23:38.310 --> 23:44.520
It should be versatile and reusable and shouldn't have to violate the const ness of any pointers, and

23:44.520 --> 23:47.220
that's going to be what we end up doing here.

23:47.220 --> 23:49.500
So that's why we have the to do for now.

23:49.500 --> 23:56.880
We know that we can access and change attributes for our health and so far we can only see that change

23:56.880 --> 24:00.720
by showing the debug information for our ability system.

24:00.720 --> 24:04.380
But in an actual game we're going to want some HUD elements.

24:04.380 --> 24:09.750
We want a UI with health bars and icons and things that show us what's going on.

24:09.750 --> 24:16.800
And so we're going to want to set up a nice system for seeing our health, and we'll do that in the

24:16.800 --> 24:17.820
next section.

24:17.850 --> 24:20.280
So great job and I'll see you soon.
