WEBVTT

00:06.840 --> 00:08.070
Welcome back.

00:08.370 --> 00:14.280
So in the last video, we made a damaged text component, which is a widget component, and it has one

00:14.280 --> 00:20.070
function that we created on the Cplusplus side, which is a blueprint implementable event.

00:20.100 --> 00:22.080
We implemented that here.

00:22.260 --> 00:25.050
Now, this widget component has its own widget.

00:25.050 --> 00:26.580
It's called damage text.

00:26.610 --> 00:30.930
We set that in the class defaults if we search for widget class.

00:32.040 --> 00:39.930
We'll see that we set it to damage text, and that's a simple user widget that just has text and an

00:39.960 --> 00:44.850
animation and it plays that animation itself whenever it's constructed.

00:44.850 --> 00:51.150
So event construct plays its own animation, and it also has a simple function that takes in a float

00:51.150 --> 00:56.550
and sets the text for this number, the damage text number.

00:56.760 --> 01:01.920
So really all we need to do is show this or create one of these components.

01:01.920 --> 01:06.300
Whenever we take damage, we're going to do that on the C plus plus side.

01:06.780 --> 01:12.480
Now, I'd like a function for constructing one of these damage numbers.

01:12.480 --> 01:15.900
And there's a couple things we have to keep in mind.

01:15.900 --> 01:22.350
One, in our attribute set, this damage meta attribute is updated on the server.

01:22.350 --> 01:25.800
So if we do something here, it's only going to happen on the server.

01:25.800 --> 01:31.870
If that attribute changed here in post gameplay effect, execute is incoming damage.

01:31.870 --> 01:34.390
So we have to take that into account.

01:34.420 --> 01:42.070
Now, if the damage is fatal, we're calling die after making sure that the target Avatar actor is a

01:42.070 --> 01:43.390
combat interface.

01:43.390 --> 01:51.070
But in the case we're activating the hit React ability and this is when we should also show floating

01:51.100 --> 01:52.870
text for damage.

01:52.870 --> 01:59.170
And in fact, you could just show floating text anyway whether the incoming damage is fatal or not.

01:59.170 --> 02:04.510
So really inside of if local incoming damage is greater than zero, we could do it here.

02:04.720 --> 02:07.150
So why don't we just do it here Now?

02:07.150 --> 02:14.980
We'd like to show the damage number and I'd like to have a function on the player controller that can

02:14.980 --> 02:18.100
spawn this damage number widget.

02:18.250 --> 02:26.350
And then what we can do is after spawning it, we can set that damage text, we can attach it to the

02:26.350 --> 02:30.040
pond so that it's just above the pond in the world.

02:30.040 --> 02:34.420
And so I'd like to have that be a function on the player controller.

02:34.420 --> 02:36.760
So let's do a couple things here.

02:36.760 --> 02:43.960
I'm going to close all tabs except for the attribute set, and I'm also going to open up my public folder,

02:43.990 --> 02:51.040
go to player and open aura player controller, and I'm going to make a show damage number function here.

02:51.040 --> 02:58.360
Now this function, I'd like to be a client RPC, so if we call it on the server, it'll be executed

02:58.360 --> 03:01.810
on the server if the controlling player is local.

03:01.810 --> 03:08.470
But if the controlling player is remote, then this function will be executed remotely on the client.

03:08.470 --> 03:10.630
So we'll add a public function.

03:10.690 --> 03:17.080
It's going to be a void function and we'll call this show damage number.

03:19.000 --> 03:22.720
And show damage number needs a float for the damage amount.

03:22.750 --> 03:29.350
That way it can pass that along to the widget component it's going to spawn and this will of course

03:29.380 --> 03:30.580
be a new function.

03:30.580 --> 03:37.060
And since it's a client RPC, it gets client and we'll make this a reliable RPC.

03:37.510 --> 03:44.230
So show damage number needs a implementation so we can create the definition writer is going to put

03:44.230 --> 03:50.920
underscore implementation here for me, which is exactly what I need and show damage number is going

03:50.920 --> 03:57.430
to construct that widget component and it needs a widget component class so it knows what type of widget

03:57.430 --> 03:58.990
component to construct.

03:58.990 --> 04:05.860
So we're going to also add a variable on or a player controller for the class to spawn.

04:06.480 --> 04:10.740
So this one will be a subclass of now it could be private.

04:10.770 --> 04:14.760
We can stick it way down here all the way down at the bottom.

04:15.510 --> 04:22.770
And this can be a subclass of of type you damage text component.

04:22.770 --> 04:25.530
That's the class we made last video.

04:25.530 --> 04:30.600
Now I'm going to add a forward declaration for that as we don't need to include its header file.

04:30.600 --> 04:39.210
So we now have you damage text component forward declared and this is going to be called damage text

04:39.210 --> 04:45.750
component class and we'll set this on the player controller blueprint.

04:45.750 --> 04:53.010
So I'm going to make it edit defaults only and we'll use this to create our new component here and show

04:53.010 --> 04:55.440
damage number implementation.

04:55.680 --> 05:00.330
Now we're going to want to know where to show that damage number because this is going to be on the

05:00.330 --> 05:01.500
player controller.

05:01.500 --> 05:08.770
And the player controller is really only going to spawn this for the player that is a human player that

05:08.770 --> 05:09.700
can see it.

05:09.700 --> 05:16.090
But we want to show this damage number just above the head of the target that's being hit.

05:16.300 --> 05:22.300
So from the attribute set, we're going to get the local player controller that actually has a human

05:22.300 --> 05:26.980
player and call this function on it so we can see that damage number.

05:26.980 --> 05:34.930
But we're going to call this function passing in the target character or actor that we want to attach

05:34.930 --> 05:37.420
or show this number above.

05:37.420 --> 05:42.490
So our RPC here should actually take in a pointer as well.

05:42.490 --> 05:47.020
So show damage number should take in a target.

05:47.050 --> 05:52.300
We can pass in an a character, for example, called Target Character.

05:52.810 --> 05:57.310
So let's go ahead and add that input parameter into the client RPC.

05:58.000 --> 06:02.020
And here we're going to check to make sure that it's a valid target character.

06:02.020 --> 06:10.630
So we're going to say if is valid target character and we can't check an incomplete type without actually

06:10.630 --> 06:12.640
including that type.

06:12.640 --> 06:16.030
So we're going to have to include the character class header file.

06:17.020 --> 06:22.540
So include and that's in game framework slash character dot h.

06:23.180 --> 06:25.070
Now we can check that pointer.

06:25.760 --> 06:32.720
We're also going to check damage text component class and make sure that is valid.

06:32.720 --> 06:36.010
And that is also an incomplete type.

06:36.020 --> 06:38.600
We're going to need to include the header for that.

06:39.290 --> 06:46.790
So include UI slash widget slash damage text component.

06:46.910 --> 06:53.390
Now if you're asking why I'm using is valid for target character and not using is valid for damage text

06:53.390 --> 07:00.170
component class well is valid checks to see if the pointer is null, but it also checks to see if that

07:00.170 --> 07:02.060
pointer is pending kill.

07:02.330 --> 07:07.490
Now this damage text component class, it's either going to be null or not null.

07:07.610 --> 07:09.830
I'm not worried if it's pending kill or anything.

07:09.830 --> 07:14.210
It's just a property that we either set on the blueprint or not.

07:14.210 --> 07:20.360
But Target character may have had destroy call on it recently, last frame or something.

07:20.720 --> 07:24.260
If it's pending kill then is valid matters.

07:24.260 --> 07:27.950
So for those of you who were wondering that that's the reason.

07:28.630 --> 07:34.810
Now, if the character is valid and the damaged text component class is valid, then we can create one

07:34.810 --> 07:42.970
of these damaged text components and we can create a new view object with new object specifying you

07:43.150 --> 07:45.280
damage text component.

07:46.450 --> 07:52.570
Now, when we create a new object, we need to specify the outer for this object, and that's going

07:52.570 --> 07:55.020
to be the player controller itself.

07:55.030 --> 07:57.280
It's going to own this object.

07:57.400 --> 08:02.140
And we can also specify a class that's our damage text component class.

08:02.410 --> 08:08.120
So once we've created this, we're going to store it in a local pointer called Damage Text.

08:08.140 --> 08:12.540
So that'll be a new damage text component called damage text.

08:12.550 --> 08:14.860
And now we've created one of these.

08:15.010 --> 08:23.800
Now after we create a widget component dynamically, we have to register it by calling register component.

08:23.830 --> 08:30.100
This is something that you probably don't see very often because when we create a component, we just

08:30.100 --> 08:35.770
construct it with create default subobject, which handles registering it for us with unreal engine

08:35.770 --> 08:38.200
for all kinds of behind the scenes stuff.

08:38.230 --> 08:44.950
We're creating one dynamically, not in the constructor, so we're manually registering this component.

08:45.160 --> 08:47.930
And I'd like to take my damage text.

08:49.130 --> 08:52.910
And I'd like to attach it to the Target character.

08:53.180 --> 09:00.590
So what I'm going to do is call attach to component and we're going to take the target character and

09:00.590 --> 09:01.820
get its root component.

09:01.820 --> 09:07.460
So we're going to attach it to the root component using the attachment transform rules.

09:09.840 --> 09:13.140
And I'm going to choose keep relative transform.

09:13.410 --> 09:18.900
So it's going to attach to the root component of the target character.

09:18.900 --> 09:25.070
But the thing is, the only reason I want to attach it is so that it starts off at the correct location,

09:25.080 --> 09:28.880
the location of the character taking damage.

09:28.890 --> 09:35.790
After that, though, I'd like to detach it so that it just floats away according to its own animation.

09:35.790 --> 09:40.140
I don't want it to follow that enemy around or that character.

09:40.140 --> 09:45.690
So after attaching it to the component, we know that it's going to play its animation right away.

09:45.840 --> 09:47.400
That's all the movement I want.

09:47.400 --> 09:54.330
So I'm going to take damage text and I'm going to call detach from component.

09:54.330 --> 09:58.500
And this requires an F detachment transform rules.

09:58.500 --> 10:01.350
I'm going to use keep world transform.

10:01.470 --> 10:05.610
So the result of this is that we'll create the new component.

10:05.640 --> 10:11.290
It's going to be attached to the target character's root component, then we'll detach it.

10:11.290 --> 10:16.600
So it's going to be left floating there and it's going to play its own widget animation.

10:16.720 --> 10:21.730
Now it's just a 99 that's going to float and fade away.

10:21.730 --> 10:28.840
What we want to do is set the damage text and the reason we created a C plus plus class called you damage

10:28.840 --> 10:34.660
text component was so that we can have a C plus plus function on it that we can call from here.

10:34.660 --> 10:35.950
So we're going to call that now.

10:35.950 --> 10:43.960
We're going to take damage text and we're going to call, set damage text and pass in the damage amount.

10:45.590 --> 10:46.710
Like so.

10:46.730 --> 10:52.400
So we'll create one of these and set its damage amount and let it animate itself.

10:52.640 --> 10:58.760
So now that our player controller has this function and it's an RPC, so we can call it on the server

10:58.760 --> 11:04.730
and for the server controlled character, it'll just execute on the server and the server controlled

11:04.730 --> 11:05.960
character will see it.

11:05.960 --> 11:12.650
But for client controlled character, it'll be called on the server but executed on the client and the

11:12.650 --> 11:13.640
client will see it.

11:13.640 --> 11:16.700
So either way this widget will be seen.

11:17.030 --> 11:23.360
Now we need to actually call this function show damage number and we're going to do that here in the

11:23.360 --> 11:24.650
attribute set.

11:24.740 --> 11:29.340
And I'd like to only do this if it's not self damage, right?

11:29.360 --> 11:40.850
So we can check if props, dot source, actor or source character is not equal to props dot target character.

11:41.540 --> 11:44.360
Otherwise this would be damage caused to the self.

11:44.360 --> 11:47.580
And I don't want to show damage numbers in that case.

11:47.610 --> 11:52.230
Now if we pass this check, then I need to get the player controller.

11:52.260 --> 12:00.720
So what I'm going to do is call you gameplay statics, get player controller.

12:01.140 --> 12:03.750
Now we're going to need to include gameplay statics.

12:03.750 --> 12:05.460
I'm just going to hit alt enter there.

12:05.490 --> 12:05.870
Thank you.

12:05.880 --> 12:12.300
Writer and get player controller requires a world context object.

12:12.300 --> 12:20.340
I'm just going to use props, dot source character and an index and that's going to give us the locally

12:20.340 --> 12:22.530
controlled player controller.

12:22.650 --> 12:25.290
Now this is just an a player controller.

12:25.290 --> 12:28.230
We need to cast it to an aura player controller.

12:28.230 --> 12:29.700
So we're going to cast here.

12:32.260 --> 12:41.800
And we'll cast to a Ora player controller and we'll store this in a local ora player controller pointer.

12:44.030 --> 12:50.630
Called we'll just call it PC and we'll wrap this in an if statement to make sure that this is a valid

12:50.630 --> 12:51.310
pointer.

12:51.310 --> 12:55.190
And looks like I clicked on the scroll bar there.

12:55.370 --> 13:01.670
So if this is a valid pointer, we'll wrap that and it looks like I'm missing an equal sign there.

13:01.700 --> 13:02.750
There we go.

13:02.960 --> 13:06.830
If this is a valid pointer, then we can show the damage number.

13:06.830 --> 13:13.610
So we can call PC show damage number and we can pass in the damage.

13:13.610 --> 13:15.380
Now we have local damage.

13:16.130 --> 13:17.090
We stored it.

13:17.090 --> 13:19.400
It's called local incoming damage.

13:19.400 --> 13:23.570
And show damage number also requires the target character.

13:23.570 --> 13:26.960
So we're going to get props, dot, target character.

13:27.320 --> 13:27.860
Okay.

13:27.860 --> 13:35.360
So if local incoming damage is greater than zero, then we check if the source character and target

13:35.360 --> 13:37.070
character are not equal.

13:37.190 --> 13:43.310
And then we get the player controller cast to aura player controller and call show damage number, which

13:43.310 --> 13:46.440
will spawn that widget component.

13:46.650 --> 13:49.560
And we can refactor this into a function if we like.

13:49.590 --> 13:52.800
This can be show floating text or something like that.

13:52.800 --> 13:58.200
So let's just really quickly go to Aura attribute set stage.

13:58.200 --> 14:05.010
We'll make a nice little private function way down here called Show Floating text.

14:05.740 --> 14:11.320
And because this is going to check both the source character and target character, I'm just going to

14:11.320 --> 14:15.520
go ahead and pass in a const reference to F effect properties.

14:16.380 --> 14:20.820
Call that props and then we won't even bother making any copies.

14:20.850 --> 14:22.870
We're just going to pass that straight in.

14:22.890 --> 14:25.680
No copies made and a float called.

14:26.410 --> 14:27.250
Damage.

14:28.030 --> 14:29.140
All right.

14:29.140 --> 14:30.940
So show floating text.

14:31.300 --> 14:33.460
We can make a definition for.

14:34.820 --> 14:38.360
We can move this to where we were working.

14:39.320 --> 14:42.010
Just under post gameplay effect execute.

14:42.020 --> 14:47.240
So I'm going to control X and move it down to the bottom so we can see what we're working with.

14:47.300 --> 14:55.940
And I'm going to take this and paste it in show floating text and instead of local incoming damage,

14:56.030 --> 15:05.420
we'll pass in damage and we'll call show floating text in place here, passing in local incoming damage

15:05.570 --> 15:06.530
and props.

15:06.530 --> 15:07.970
Actually, that's backwards.

15:07.970 --> 15:09.650
Props should be first.

15:10.700 --> 15:12.440
So now we have show floating text.

15:12.470 --> 15:14.800
Now this could be a const function.

15:14.810 --> 15:17.780
Let's go ahead and clean that up by making it const.

15:20.600 --> 15:24.530
And now show floating text handles, floating text.

15:24.530 --> 15:29.360
And our player controller handles the replication side of this.

15:29.570 --> 15:35.980
So really all we need to do is make sure that the player controller has a damaged text component class.

15:35.990 --> 15:43.490
So why don't we compile launch, set that damage text component class and see if all of this works?

15:45.540 --> 15:53.400
So I'm going to go ahead and let these editors open up and go back to blueprints and player and BP or

15:53.430 --> 15:58.530
a player controller, and we'll set that damage text component class.

15:58.560 --> 16:00.330
I'm going to search for damage.

16:00.360 --> 16:01.560
Here it is.

16:01.560 --> 16:04.770
And we created BP damage text component.

16:04.770 --> 16:06.510
And now that's set.

16:06.540 --> 16:09.360
Now BP damage text component.

16:09.390 --> 16:12.750
Once we spawn it, we're going to call set damage text.

16:12.750 --> 16:13.380
Right?

16:13.380 --> 16:18.930
And that means we're going to update the damage text on the widget that belongs to it.

16:18.930 --> 16:26.310
But we also want to make it clean up itself because there's going to be a lot of these spawned all over

16:26.310 --> 16:27.140
the place.

16:27.150 --> 16:29.550
They should all destroy themselves.

16:29.550 --> 16:32.100
So I'm going to set a delay.

16:34.220 --> 16:36.910
And this will be a delay for one second.

16:36.920 --> 16:42.830
And after one second, I'm going to call destroy component.

16:43.800 --> 16:49.020
And that way the component itself will be destroyed after we've called this.

16:49.750 --> 16:55.060
And because it's destroying itself, it's going to destroy its own user.

16:55.060 --> 16:58.510
Widget damage, text and damage.

16:58.510 --> 17:00.670
Text has its animation.

17:01.500 --> 17:05.490
And that animation lasts for it looks like one second.

17:05.520 --> 17:08.520
So that delay of one second is perfect.

17:09.640 --> 17:13.810
So the last thing to do is test this out by pressing play.

17:14.050 --> 17:17.680
Looks like I got some shadow artifacts there.

17:17.830 --> 17:20.140
Nothing a good old reset won't fix.

17:20.140 --> 17:24.160
But let's see if our damage text will work.

17:26.410 --> 17:27.490
I'm not seeing it.

17:27.490 --> 17:34.490
So I'm going to need to go to Aura attribute set and let's just make sure that we're getting this far

17:34.510 --> 17:39.970
running in debug mode so I can press play, I can do some damage.

17:40.180 --> 17:42.130
We are making it this far.

17:42.130 --> 17:48.250
We have some valid props and let's see what our local incoming damage is.

17:48.250 --> 17:49.540
It's 16.

17:49.600 --> 17:50.560
Interesting.

17:50.560 --> 17:53.680
We can step into show floating text.

17:53.680 --> 17:55.870
We can see if we make it this far.

17:55.870 --> 17:59.470
It looks like we're not making it this far.

17:59.470 --> 18:01.810
We're not making it into this if statement.

18:03.900 --> 18:12.510
So doing another fireball or making it this far, We get this far and it looks like my props source

18:12.510 --> 18:14.300
character is null.

18:14.310 --> 18:18.710
We can see where we're setting that source character and set effect properties.

18:18.720 --> 18:20.970
So let's see how we're setting that.

18:21.600 --> 18:28.500
It looks like we're taking the source controller and calling git pawn on it so we may not be setting

18:28.500 --> 18:34.800
source controller looks like we're taking our source ability system component and getting the player

18:34.800 --> 18:37.140
controller from ability actor info.

18:37.260 --> 18:43.800
But if that's null, then we're trying to get it from the source Avatar Actor Let's go ahead and just

18:43.800 --> 18:45.420
place a breakpoint there.

18:46.900 --> 18:54.060
I'm going to continue and launch of Fireball and we'll see what happens.

18:54.070 --> 18:57.550
The source controller here is BP or a player controller.

18:57.550 --> 18:58.690
That's not null.

18:58.690 --> 19:00.400
So I'm going to continue.

19:00.580 --> 19:03.010
We'll make it to show floating text.

19:03.190 --> 19:05.770
Okay, So source character is null.

19:05.950 --> 19:08.380
The player controller is not.

19:08.410 --> 19:10.900
And I'm seeing the problem already.

19:10.900 --> 19:13.810
It's actually a human error right here.

19:13.810 --> 19:17.080
We're setting a local variable called source character.

19:17.080 --> 19:20.530
We're not setting props, dot source character.

19:20.530 --> 19:22.510
We should be setting that here.

19:22.510 --> 19:29.590
So once we get our source controller, that is valid, but we're never actually setting props dot source

19:29.590 --> 19:30.850
character here.

19:30.850 --> 19:32.140
That's what we need to do.

19:32.140 --> 19:34.480
So I'm going to go ahead and click Stop.

19:35.650 --> 19:41.680
And right here I'm going to change this to props dot source character.

19:41.680 --> 19:43.990
And now we should be setting that.

19:44.020 --> 19:50.350
And I don't think I need these breakpoints, so I'm going to go ahead and run in debug mode and see

19:50.350 --> 19:51.730
if that fixes the problem.

19:51.730 --> 19:56.770
So that's something that I probably rushed through when I was making this function.

19:56.770 --> 20:03.250
You may have actually not made that mistake, but now that we're actually setting that source character

20:03.250 --> 20:07.300
in the props, we should be able to see this work.

20:09.460 --> 20:12.040
So I'm going to open the aura player controller again.

20:13.620 --> 20:18.660
Search for damage, make sure that that damage text component class is set and it is.

20:18.660 --> 20:20.430
And I'll do some damage.

20:22.930 --> 20:23.650
Okay.

20:23.650 --> 20:25.180
So we're not seeing it.

20:26.530 --> 20:32.530
But at least at this point, we can check to see if our player controller is valid.

20:34.980 --> 20:38.190
And we are making it inside here this time.

20:38.190 --> 20:45.480
So now we're calling show damage number passing in, damage and passing in a valid target character.

20:45.810 --> 20:48.810
Let's go into the player controller now.

20:49.600 --> 20:56.740
And actually, I'm noticing here that when we create the new object that we should not use this.

20:56.830 --> 21:00.730
We should actually be using the target character as the outer.

21:00.730 --> 21:03.580
We're going to be attaching it to the target character.

21:03.820 --> 21:09.010
So that is what we'd like to set as the outer.

21:09.010 --> 21:14.260
So with that, let's go ahead and give this a try and we'll see if this works.

21:17.070 --> 21:19.800
And we can go up to an enemy.

21:20.250 --> 21:24.600
And I do see floating text now.

21:24.600 --> 21:26.280
It doesn't quite look right.

21:26.280 --> 21:30.620
But if we look at these enemies over here, they're kind of facing this way.

21:30.630 --> 21:35.600
We can see that their numbers are kind of angled a little bit.

21:35.610 --> 21:41.010
It's a little hard to see, but that's because we're showing those widgets in world space.

21:41.010 --> 21:47.670
So if we go to BP damage text comp and search for space, we see that space is set to world.

21:47.670 --> 21:49.920
We want it in screen space.

21:49.920 --> 21:52.140
So setting that to screen space.

21:53.490 --> 21:56.100
Now we see those numbers looking good.

21:57.190 --> 22:07.330
Now, if you're really perceptive, you'll notice that the letters, the numbers actually in WPP damage

22:07.330 --> 22:10.930
text get a little bit pixelated when they get larger.

22:10.930 --> 22:12.890
That's because we're scaling up.

22:12.910 --> 22:16.110
See, if I zoom in a little, it's it's hard to see.

22:16.120 --> 22:18.550
Actually, if I zoom in, it looks just fine.

22:18.550 --> 22:24.100
It's not until we play the animation on the screen that it looks sort of pixelated.

22:24.720 --> 22:26.640
Now, there's a way to get around that.

22:26.640 --> 22:30.870
And the way is to never scale above a scale of one.

22:30.900 --> 22:36.060
We can start off at a smaller scale, go up to one and then go down.

22:36.060 --> 22:40.560
So that's a sort of way to make sure that you never get pixelated.

22:40.710 --> 22:47.650
So instead of going from 1 to 2.5, we could go from a smaller value.

22:47.670 --> 22:53.070
Now, if we want that same ratio, we could just take one divided by 2.25.

22:53.710 --> 22:56.300
And we can start off at 0.44.

22:56.320 --> 23:01.210
So instead of starting off at one, we start off at 0.44.

23:04.970 --> 23:12.080
For both X and Y, and then we go up to one instead of 2.25.

23:12.230 --> 23:14.990
And then we go down to 0.44.

23:16.670 --> 23:19.520
Now that means this is a lot smaller, right?

23:19.520 --> 23:26.610
So what we can do is scale up our actual text font by a factor of 2.25.

23:26.630 --> 23:34.610
So instead of 26, we can take 26 times 2.25 and that would put us at about 60.

23:34.640 --> 23:36.890
We'll make it 59.

23:36.890 --> 23:44.690
So that is the largest that it can be, but it starts off smaller, gets bigger and gets smaller again.

23:44.690 --> 23:45.710
Let's see how this looks.

23:45.710 --> 23:47.570
That might be a little too large, but.

23:48.450 --> 23:49.620
We'll see.

23:50.070 --> 23:51.420
Yeah, that looks better.

23:57.260 --> 23:59.960
And we have damage numbers.

24:00.770 --> 24:02.280
Beautiful.

24:03.480 --> 24:07.230
And that really does add quite a bit to the game.

24:07.230 --> 24:08.210
I really like it.

24:08.220 --> 24:13.740
Damage numbers are one of my very favorite mechanics to implement, so that looks good.

24:13.740 --> 24:16.920
And because our size is bigger, we'll make it 58.

24:16.950 --> 24:21.120
I do want to make sure that we have a good enough outline.

24:21.120 --> 24:23.550
I'll make our outline size too.

24:23.790 --> 24:25.770
Let's just test that out.

24:26.920 --> 24:28.320
Yeah, that looks good.

24:28.330 --> 24:32.890
And if you like, you can play with other factors like letter spacing.

24:32.900 --> 24:34.930
It's totally up to you.

24:36.370 --> 24:38.680
Yeah, that looks pretty good.

24:39.830 --> 24:41.990
I might actually keep it at about 100.

24:42.020 --> 24:43.520
Anyways, enough tweaking.

24:43.520 --> 24:44.630
We've got it working.

24:44.630 --> 24:45.410
It's looking great.

24:45.440 --> 24:49.100
Now there are a few things that I'd like to do in addition to this.

24:49.100 --> 24:50.530
Some more ambitions.

24:50.540 --> 24:56.150
We're going to want to see if we have a critical hit, a blocked hit, any number of special combat

24:56.150 --> 24:56.930
mechanics.

24:56.930 --> 25:03.260
And I'd like this number to be a different color, depending on whether it was a blocked hit or a critical

25:03.290 --> 25:03.680
hit.

25:03.680 --> 25:08.360
And I'd also like to show some text showing if we got a blocked or a critical hit.

25:08.360 --> 25:12.680
That's just always really exciting when we get those types of things.

25:12.680 --> 25:16.760
And so that's some stuff to look forward to in the videos to come.

25:16.760 --> 25:19.010
But for now, we have damage numbers.

25:19.010 --> 25:20.240
It's looking great.

25:20.240 --> 25:23.960
Excellent job and I'll see you in the next video.
