WEBVTT

00:06.850 --> 00:08.110
Welcome back.

00:08.140 --> 00:15.430
Now we've created our input config and some input actions and we've linked those up to new gameplay

00:15.430 --> 00:15.850
tags.

00:15.850 --> 00:22.930
We kind of did a lot of things in the last video, but now that we have an input config, we want a

00:22.930 --> 00:27.130
way to bind callback functions to inputs.

00:27.160 --> 00:30.790
Now we've done this already in our player controller.

00:30.820 --> 00:38.380
Let's go into our player folder and open our player controller and we can go ahead and get our CP file

00:38.380 --> 00:39.580
open here.

00:39.580 --> 00:46.540
And if we scroll on down to set up input component, we'll see how we bound a callback function called

00:46.540 --> 00:51.160
Move to our input action called Move Action.

00:51.340 --> 00:58.990
Now this is done using a function on the enhanced input component called bind action.

00:59.230 --> 01:03.130
Now we can go to the definition and see how this works.

01:03.350 --> 01:13.460
Here's Bind Action says binds to an object you function and it takes a trigger event, a U object and

01:13.460 --> 01:14.810
a function name.

01:14.810 --> 01:17.210
Actually, that's not the one we're using.

01:17.390 --> 01:23.150
We're using bind action, the one that takes in an actual function.

01:23.150 --> 01:30.440
So when you see something like T method pointer, we've seen wrappers for function pointers before.

01:30.440 --> 01:35.210
So even though they look a bit cryptic, we know that that's just a function pointer.

01:35.330 --> 01:38.090
Well, look at these variadic inputs.

01:38.090 --> 01:47.750
We have a Variadic var types, variable types, and this seems to indicate that this template function

01:47.750 --> 01:49.820
can take a variable number of arguments.

01:49.820 --> 01:52.400
Well, that's exactly right.

01:52.400 --> 01:58.230
It can take a function that can take zero or more input parameters.

01:58.250 --> 02:06.890
So what we can do is we can actually bind functions to inputs that can take input parameters like,

02:06.920 --> 02:08.810
say, gameplay tags.

02:09.080 --> 02:15.980
So what we're going to do is take advantage of the versatility of bind action, and we're going to give

02:15.980 --> 02:24.350
ourselves the ability to loop through our input config, which has an array of input actions and bind

02:24.350 --> 02:27.390
functions for those input actions.

02:27.390 --> 02:34.670
So we're going to do all this on the player controller, but our player controller is simply calling

02:34.670 --> 02:38.420
bind action on the input component.

02:38.420 --> 02:46.670
But I'd like to have our own custom input component so our player controller doesn't have to be taking

02:46.670 --> 02:49.970
care of things that the input component should be taking care of.

02:50.150 --> 02:56.030
The player controller should have to just call a single function and pass in any function callbacks

02:56.030 --> 02:59.630
that we want to bind for any given input.

02:59.630 --> 03:07.370
In fact, I'd like to be able to pass in the whole input config data asset to our input component and

03:07.370 --> 03:09.410
just let the input component handle it.

03:09.410 --> 03:13.670
So for that reason we're going to make a custom input component class.

03:13.820 --> 03:17.510
So I'm going to launch the editor so we can make this class.

03:18.170 --> 03:23.000
So our new class will be an enhanced input component class.

03:23.390 --> 03:30.100
So let's go ahead and go into C plus plus classes or public and we have an input folder.

03:30.110 --> 03:31.900
This is a perfect place for it.

03:31.910 --> 03:34.820
So let's make a new C plus plus class.

03:35.030 --> 03:40.460
And the class that I'm interested in is enhanced input component.

03:40.460 --> 03:42.020
I'm going to choose that.

03:42.170 --> 03:50.570
We'll put this in the input folder and I'd like to call this simply aura input component.

03:50.570 --> 03:57.860
So we're going to create the class close out of the editor and we'll return back to the C plus plus

03:57.860 --> 03:58.430
side.

03:58.460 --> 04:04.310
Now, I'm only interested right now in having my player controller open.

04:04.310 --> 04:10.520
I don't need enhanced input component, I don't need or a gameplay tags right now and I'll go ahead

04:10.520 --> 04:17.910
and leave my aura input config, but let's get our input folder open and open aura input component.

04:17.910 --> 04:25.680
So aura input component is an enhanced input component and if we configure our project correctly, we

04:25.680 --> 04:30.930
can set this to be the default input component being used.

04:30.930 --> 04:39.240
Now I'd like a function here that we can call from our player controller that will bind inputs to callbacks,

04:39.300 --> 04:43.260
and I'd like those callbacks to be parameters to a function.

04:43.260 --> 04:47.070
I'd like this function to just kind of handle things for us.

04:47.070 --> 04:53.070
So let's start out by adding a public section and making a function that returns void and it's going

04:53.070 --> 05:01.680
to be bind, ability, actions, and this will bind input actions for our abilities and I'd like it

05:01.680 --> 05:03.540
to take an input config.

05:03.690 --> 05:12.390
So I'm going to pass in a const u aura input config pointer and we're going to go ahead and include

05:12.390 --> 05:15.360
the header for it rather than forward declare.

05:15.360 --> 05:18.840
And the reason why will be apparent in just a second.

05:18.840 --> 05:21.990
So this will be aura inputs.

05:22.890 --> 05:28.470
Config.h and this input will be called input config.

05:28.860 --> 05:35.040
Now the reason I'm not forward declaring this is because I'd like this to be a template function and

05:35.040 --> 05:39.060
if this is a template function, we're going to define it right here in the header file.

05:39.060 --> 05:42.810
So we're just going to use the input config header right here.

05:42.840 --> 05:48.600
So if this is going to be a template function, I need to use the template parameter followed by angle

05:48.600 --> 05:53.880
brackets and any class and type names that we're going to use here.

05:53.910 --> 06:02.180
Now I'm going to say class, user class, and my second input is going to be of this type user class.

06:02.190 --> 06:07.230
It's going to be a pointer to it and I'm going to call this object.

06:07.410 --> 06:13.860
And that's because we're going to be calling bind, action in bind, ability, actions, and that requires

06:13.860 --> 06:15.150
a user object.

06:15.700 --> 06:19.240
Now, we're also going to have some other types as well.

06:19.600 --> 06:26.890
And I'm going to use type name followed by pressed funk type.

06:26.980 --> 06:32.830
And this is going to be the type of the function I'd like to bind for when an input is pressed.

06:33.040 --> 06:36.150
So that'll be my next input parameter.

06:36.160 --> 06:44.650
It'll be pressed funk type called Pressed funk, and that will be our pressed function.

06:44.650 --> 06:51.460
And I'd like to do this for a released function and a held function so we'll have functions that we

06:51.460 --> 06:57.910
can bind to all of our input actions for when they're pressed, released and held.

06:57.910 --> 07:01.900
So we'll have another template type name.

07:02.790 --> 07:08.820
Called released funk and another template type name.

07:09.590 --> 07:11.750
Called Held Funk.

07:11.810 --> 07:17.840
Actually, we'll call this released funk type and held funk type.

07:18.350 --> 07:23.120
And after Pressed funk, we'll have released funk type.

07:23.240 --> 07:26.150
We'll call this released funk.

07:28.160 --> 07:32.970
And then we'll have our held funk type called Held Funk.

07:32.990 --> 07:41.360
So this function is a template function capable of receiving functions or function pointers and whatever

07:41.360 --> 07:43.760
that function signature is.

07:43.790 --> 07:44.660
It doesn't matter.

07:44.660 --> 07:51.830
This is a template, so we can just pass in the function we want and this function will handle it.

07:51.860 --> 07:56.780
Let's generate the definition and it's going to go right here in the header file.

07:56.780 --> 08:01.760
And that's why I didn't want to forward declare or input config.

08:02.210 --> 08:05.750
Now the input config is one of the input parameters.

08:05.750 --> 08:15.210
We're going to check that right off the bat that should not be a null pointer and writer has automatically

08:15.210 --> 08:18.780
included something that it thought I wanted.

08:18.780 --> 08:21.290
Autocompleted not the case.

08:21.310 --> 08:25.940
I'm going to control z that input config.

08:25.950 --> 08:26.730
There we go.

08:27.590 --> 08:36.230
And after checking input config, I want this function to loop through our input configs ability input

08:36.230 --> 08:36.770
actions.

08:36.770 --> 08:39.080
So look at our input config for a second.

08:39.110 --> 08:42.500
We have a t array of for input actions.

08:42.500 --> 08:44.500
I'd like to loop through this.

08:44.510 --> 08:48.350
So back in our input component, we're going to loop through it.

08:48.380 --> 08:53.420
We'll have a for loop, we're going to say const F or a input action.

08:53.420 --> 08:59.360
It'll be a const reference called action and we're going to loop through input config.

09:00.820 --> 09:02.170
Ability input actions.

09:02.170 --> 09:04.210
That's a public variable, after all.

09:04.390 --> 09:06.750
So what are we going to do for each of these?

09:06.760 --> 09:12.880
Well, we're going to bind the pressed, released and held functions for all of them.

09:13.210 --> 09:18.860
So why are we binding the same functions to all of our inputs?

09:18.880 --> 09:23.060
Well, because we have the ability to pass along a gameplay tag.

09:23.080 --> 09:29.800
So if we can bind the same three functions pressed, held, and released to all of our input actions

09:29.800 --> 09:36.160
and we can identify those inputs by tag, well then we can pass those along to the ability system component

09:36.160 --> 09:39.120
which can then decide which abilities to activate.

09:39.130 --> 09:41.050
That's the idea here.

09:41.380 --> 09:47.860
So what we're going to do is we're going to say if action dot input action, we'll get that input action.

09:47.860 --> 09:52.420
We'll make sure that's not a null pointer first and we'll have an end here.

09:52.420 --> 09:57.280
And action dot input tag and we'll say Dot is valid.

09:58.000 --> 10:00.520
Make sure that's a valid tag as well.

10:00.530 --> 10:05.930
And if we make it inside here, we can bind those functions using bind action.

10:05.930 --> 10:07.520
So here's how we're going to do it.

10:07.550 --> 10:13.220
We're first going to check if our held func is valid and we'll call bind action.

10:13.220 --> 10:21.290
This is a function on the input component after all, which we're inside of and it takes an input action.

10:21.290 --> 10:23.630
So we have our for input action.

10:23.630 --> 10:24.800
It's called action.

10:24.800 --> 10:31.490
We can pass in the input action and this is going to be for our held function.

10:31.490 --> 10:37.550
So we're going to use a trigger event and for the held function we're going to use triggered.

10:37.580 --> 10:46.730
Triggered is the option that we pass in if we want this function callback called every frame as long

10:46.730 --> 10:48.170
as the input is held.

10:48.170 --> 10:51.680
And that's why we're going to use our held function for this.

10:51.680 --> 10:56.230
So the trigger event is the second input for bind action.

10:56.240 --> 10:58.250
Next is the object.

10:58.280 --> 11:01.670
That's why we needed our object input parameter.

11:01.670 --> 11:07.760
And then after that we have our function that's going to be our held func.

11:08.210 --> 11:09.440
Now here's the thing.

11:09.440 --> 11:16.040
Bind action can take a variable number of arguments and if we pass in more than this then those arguments

11:16.040 --> 11:19.940
will be passed along to our held function and our held function.

11:19.940 --> 11:27.020
If we make one that can take a gameplay tag, it'll receive that tag and we're going to pass along action

11:27.020 --> 11:28.640
dot input tag.

11:28.790 --> 11:35.480
So any input tag associated with a given action is going to be passed along into its callback.

11:35.480 --> 11:36.870
How cool is that?

11:36.890 --> 11:42.110
So as long as we're holding down a given input, then its callback.

11:42.110 --> 11:47.510
Once we call bind ability actions and pass the callback into it is going to be triggered.

11:47.510 --> 11:51.560
It's going to be called every frame as long as that input is held.

11:51.590 --> 11:53.840
That's how the held func will work.

11:53.930 --> 11:56.000
Now we also have other ones.

11:56.000 --> 12:00.080
I don't know why I did held first it was the last input parameter.

12:00.080 --> 12:03.470
So let's do the pressed and released ones as well.

12:03.470 --> 12:06.140
But I'll have held last there.

12:06.440 --> 12:07.670
So let's do the pressed.

12:07.670 --> 12:13.310
We'll say if pressed func and we'll do the same thing we're going to call bind action.

12:14.060 --> 12:23.660
We pass in action dot input action and then for each trigger event for this one we're going to use started.

12:23.660 --> 12:25.850
So e trigger event.

12:26.560 --> 12:28.480
There it is started.

12:28.660 --> 12:35.500
And this means that as soon as an input is pressed, this function callback that we're going to bind

12:35.500 --> 12:39.490
to it will only be called once as soon as it's started.

12:39.520 --> 12:42.060
That's why we have our pressed func.

12:42.070 --> 12:44.140
So next is the object.

12:44.140 --> 12:51.070
We need to pass that in and then our pressed func and then we can pass in any input parameters we're

12:51.070 --> 12:54.040
going to pass in action dot input tag.

12:54.040 --> 12:57.910
So our pressed func will receive the input tag as well.

12:57.910 --> 13:00.040
And then finally we have the released func.

13:00.040 --> 13:03.820
So we'll say if released func oh I hit enter again.

13:03.820 --> 13:10.060
It's going to do the same thing it did before and I don't think it included anything for me.

13:10.090 --> 13:14.410
One of those things that writer tends to do that's a little annoying.

13:14.410 --> 13:17.080
So we're going to say released func.

13:18.220 --> 13:20.170
And we'll call Bind, action.

13:20.530 --> 13:22.240
We're going to pass in action.

13:22.480 --> 13:22.960
Input.

13:22.960 --> 13:23.830
Action.

13:24.220 --> 13:25.300
We're going to use our E!

13:25.300 --> 13:27.070
Trigger event.

13:28.220 --> 13:32.270
And for this one for released we pass in completed.

13:32.990 --> 13:39.140
That means that our callback will be called when we stop holding down that input.

13:39.170 --> 13:48.020
We pass in object next followed by the function released func and then any inputs we're going to pass

13:48.020 --> 13:51.380
in the tag action dot input tag.

13:52.040 --> 13:59.210
So now we have this function that once we call it, we can pass in a input config data asset.

13:59.240 --> 14:04.640
We can pass in a user object and we can pass in functions three functions.

14:04.670 --> 14:10.670
These will be callbacks and they can receive input tags, they can receive gameplay tags for input.

14:10.790 --> 14:18.620
And thanks to this function, those functions will be bound to each of the input actions for when they're

14:18.620 --> 14:20.660
pressed, release and held.

14:21.280 --> 14:22.870
So this is great.

14:22.900 --> 14:31.630
Now we just need to tie it all together by going into our player controller class and calling that function.

14:31.630 --> 14:32.370
What did we call it?

14:32.380 --> 14:34.840
We called it bind, ability action.

14:34.840 --> 14:39.700
So here in the player controller, we need to call that passing in three functions.

14:39.730 --> 14:45.040
The functions we want called when our inputs are pressed, released and held, and we're going to make

14:45.040 --> 14:49.300
those function callbacks and tie all this together in the next video.

14:49.330 --> 14:50.460
So great job.

14:50.470 --> 14:52.150
I'll see you in the next video.
