UE5 C++ Enhanced Input - 2 - Bind C++ Functions to Input Actions
Vložit
- čas přidán 22. 08. 2024
- UE5 C++ Enhanced Input - 2 - Bind C++ Functions to Input Actions
We continue learning about Enhanced Input by converting a basic Axis Mapping-driven callback function to use Input Actions in the Enhanced Input system
Get the new Unreal Engine 5 C++ The Ultimate Game Developer Course here: www.udemy.com/...
This is freaking solid. I jumped into a course on Udemy to figure out there is a free source of learning on enhanced input. God bless a YT and people who share knowledge.
In total, I watched 4 videos on the subject. They didn't work, and I didn't understand how Unreal could link bindAction (C++) and inputAction (Blueprint). Then I watched your video, and you were the first at 37:52 to discuss this part. Now I understand how the link is made, and it works. It just goes to show that sometimes you have to persevere. A big thank you, you're a god!
Little tip for folks if you don't want to type the debug command constantly....open your character blueprint view graph. Bind a key (like 1) to execute the console command showdebug enhanced input
So much better when just doing the debugging than it is typing it out constantly.
Til next time with additional tips!
Also, if you don't want to do that. If you type it once you can just hit the up arrow key to bring up the last line typed (during that session).
great tip thank you :D
For noobs like me, just search "1 event" to find the bind function and then if you want to be able to turn it off, bind just the command "showdebug" to another key like number 2.
You manage to strike the perfect balance between explaining every necessary detail without making the viewer feel like the video will never end! Kudos!
Thanks for this, Stephen. It's the most comrehensive guide I've seen for the new input system so far. Very helpful!
As a quick side-note: I don't mean to come across as pedantic, but I just want to point out that you actually can forward declare for references just like you can for pointers, all the same rules apply. Internally they're still pointers so the sizes can be worked out.
Thank you Suna, yes I misspoke, I forgot that we can forward declare with struct on a reference :)
hey guys i can tell you both know what you dowing ,have a noob questio (im playing around with unreal blueprints but never started c++) so my questio ...is it ok to just learn unreal editor and blueprints or should i definetly start c++ too ,is the code in c++ better for the final game or with blueprints can be the same result (actualy 2 questions :D ) thanks in advance!
@@DruidMechanicsGameDevelopment hey guys i can tell you know what you dowing ,have a noob question (im playing around with unreal blueprints but never started c++) so my questio ...is it ok to just learn unreal editor and blueprints or should i definetly start c++ too ,is the code in c++ better for the final game or with blueprints can be the same result (actualy 2 questions :D ) thanks in advance!
@@MaxStudioCG2023 Do you want to be a gameplay programmer or more of a designer? If you want to be a programmer, you should learn C++!
@@DruidMechanicsGameDevelopment kinda want to do both and definetly a programmer ! thank you for anser, definetly i will start c++ too!
@14:49 Just a head up for people starting with UE5.1. "add mapping context" sometime doesnt show up unless you unchecked the box at the top right of the search "Context Sensitive". Took me a few hours to find it.
very helpful, i was disappointed, with moment when include files didn't work, after added module "Enhanced Input", but this video make me smile and im forget about this problem. Love u brother👊
Regarding the discussion of pointer scope at 27:26, another advantage is that since the pointer is scoped to the if block, you also are protected against trying to access it later on. You would have to check for a null pointer again and it would be easy to forget.
We'll I'm glad that you showed people how to set this up the way you did. I've noticed a lot of C++ Elitists are only showing people how to do this from C++ only so that your Input Mappings are Hard Coded in C++.....not really sure why anyone would want to do that lol.
I mean I appreciate the understanding that comes along with this but honestly the old Input System is on it's way out and none of these Starter courses are actually showing you how to set this up with Enhanced Input which seems kind of critical to me considering that the old way of doing it may be removed in Unreal Engine 5.5 for all I know.
I understand easy when topics are explained as you do. Very good . Thanks
God I love the tutorial! That is why I bought Stephen courses on Udemy!
Nice video! Just one note, CastChecked has another advantage: It is converted to static_cast in Shipping, resulting in better performance (removing the dynamic cast and checks).
For instance, you may use CastChecked in your example also for the APlayerController cast, if you have the design assumption that the pawn cannot be controlled by AI.
Anyway, this is irrelevant outside of methods that are not part of the update/tick loop, there is no benefit on saving on dynamic casts for methods called sporadically.
Thank you for sharing that!
Thanks for this, just upgraded to 5.1 and noticed the deprecation. New system looks so much easier to do advanced things! Primer in the last video was golden and this is a good walkthrough on converting doesn't seem TOO different in a coding perspective just shorter more sensible names! Less mess is always good!
Was looking for something else when I stumbled on this vid. Good stuff. Not the specific thing I was looking for but it was a great presentation of the system and what actually is happening intead of the usual "Do this for thing to happen"
32:30 u can just open ue5 open the tool dropdown menu and click on refresh visual studio code is much more faster this way
Hello. Around 42:00 you said that we cannot forward declare something that is not a pointer. This statement is not true. You can forward declare a reference also to a struct/class. So in your example, you could have forward declared FInputActionValue by using : struct FInputActionValue. In you .cpp file then, you could have included the right header file. Even if struct are small in size, it does not change the fact that you need to avoid over-inclusion in the .h file.
I can confirm. I did not know this but Rider autosuggested to add forward declaration and it just added "struct FInputActionValue;" in the headers of the .h file i.imgur.com/KuiRYfE.png
Basically from the compiler point of view references and pointer are similar, they use weak linkage that's why if you can forward declare pointers, you can do the same with references.
Thank you sir. You are a great teacher. I really liked your toon tanks tutorial on Udemy and for this one it helped out that you showed the documentation and how to do enhanced input in blueprint first.
Although it would help if you link the docs in the description since what ever reason i cannot find them easily when i search the exact things you are searching...
Thanks Stephen. I just started you course on Udemy and falling back here for a great explanation about all the enhanced input system. As always, all is really clear 👍
Thank you so much! The delegate functions with FInputActionValue is so new and I didn't know how else to not run into compile errors until I saw your video.
Man, adding the new module and then having to delete the intermediate/binary and saved directory isnt super graceful or intuitive.
This is a must watch for anyone using UE5, Thank you!
First of all.. I like Birds,..that's why this is a superb tutorial.
Secondly.. i like Birds so much...
Nice video. thanks.
I like turtles
I thought you were skipping compiles in the video but then I realized you just have a good computer :D
Incredibly helpful explanation that teaches everything perfectly!
Loving the series! Excited to keep going!
Thank you for this series, this is by far the best explanation and code walkthrough I have seen on the topic. As someone who has built their prototype in 5.2 through blueprint, this is exactly what I was after for my cpp project
A quick note, I found that simply including EnhancedInputSubsystems.h in the header rather than the cpp that none of the other includes were required other than EnhancedInputComponent.h in the cpp file. I have also found that InputActionValue.h causes UInputAction to be a non explicit import type, whereas "InputAction.h" resolves this. I presume this is due to version changes but any clarification that you may have would be welcome
Không thể tin nổi vì kiến thức đồ sộ này được chia sẽ miễn phí.
After assigning the mapping context in the UI to the C++ UInputMappingContext pointer , could we loop through it's mappings and bind each one to the correct functions, instead of creating properties for the user to assign the action mappings via the UI? Seems like we're duplicating something that's already been set up in the mapping context.
I too prefer to declare variables outside an "if" statement. I prefer readable code over being a line minimalist.
it's not line minimalism, it's ensuring that you can only access a pointer inside a scope where you _know_ it's valid. potential memory savings etc are less relevant, and probably solved by the compiler anyhow.
What's the benefit of setting this up with c++ as opposed to blueprints?
It dawned on me! The default Macro "BindAction" passed in the signature "FEnhancedInputActionHandlerValuesSignature", so the callback function took the param "const UInputAction*"...😅 I always thought that "BindAction" could only pass "VarTypes...". Thanks!
I started the class on 5.1, and wasnt able to get a response from BP Bird -
It turns out it was because i tried using the default IA_Move that came with the project. If anyone taking the class has also started with 5.1, make sure to create your OWN IA_MOVE like in the video instead of trying to use the one that comes with the project
You're a godsend Druid
I am a little bit confused but yeah we'll continue with the tutorial no problem, Boss
Thanks for this Video. What I'm missing is the way to unbind the action mapping (C++)
Solved. In case someone needs it too:
// unbind all bindings for this object
EInputComponent->ClearBindingsForObject(this);
@@petergrundmann8283 Thx Peter!
For me, deleting files and generating vs files didnt worked, but only generating worked
Always make backups when you deleting something
For me, following the showdebug EnhancedInput command, the text below STATE Playing does not show up. What must be the reason?
My guess is that it's part of the starter content assets he's using
AMAZING ULTRA COOL thank you very much!!
Thank you for comprehensive explanation!
Thanks for videos about Enhanced Input! I subscribed to you.
Crazy that it takes us almost an hour to do what BP does in less than a minute and we still have to go to the bp anyways to set variables.
I am the only one to find weird that you have to add a member InputMappingContext, which already holds an array of InputAction AND add an InputAction member which is supposedly contains inside the context mapping ? It is not your fault, I think there is a missing piece in the InputAction class which is a FGameplayTag. With Tag we could identify which InputAction could be bind to a specific callback. Otherwise, if you had multiple contexts, you absolutely need multiple members of InputAction that are supposed to be in each Contexts. Anyway, It was my late night 2 cents ;)
Thought I was missing something...didnt quite understand why we have to bind the IA if it is already within the IMC. All in all it seems quite a lot of effort to "just" get the input up and running . But well, maybe its just a "get used to it and it will be a habit" thing...
Iv learn so much from this. Thanks dude!
Hey Stephen,
nice video with a comprehensive explanation.
I have one question that's been bugging me: what does CastChecked do?
You said it asserts that the result is not a nullptr. However, I looked at the code in Casts.h and did not find any assertions, like check(Result).
It looks like it uses Cast, then logs error if the result is a nullptr and then just returns the result. So it actually might be a nullptr, right?
Also: if CastChecked result could not be a nullptr, why does the ThirdPersonTemplate code check for it in the SetupPlayerInputComponent function?
I am using UE 5.1.1, maybe something changed here from UE 5.0?
Thanks
Thank you so much! Love your courses!
If anyone else runs into the issue of being unable to launch the editor from Visual Studio like me. After deleting the temporary files and rebuilding, You have to set your project back to Startup Project.
Whats the benefit of doing it like this instead of using Blueprints? In BP, this was a five second effort. this took 2 hours to explain and setup with dozens of includes, adding modules and stuff?
I wonder too ?
Accidentally declared MoveAction with type UMappingContext instead of UInputAction and I spent the last five hours becoming a leading expert in the field of Binding Inputs to figure out what was wrong hahahaha. Sometimes it is like that with programming, right? xD
Indeed sometimes it is 😆
@@DruidMechanicsGameDevelopment haha btw i thoroughly enjoyed ur unreal engine course, I just wish you would publish a Blender course as well 👍🏼👍🏼🤝🤝
@@andreashadjisolomou1260 I have. It's called Blender Fundamentals - Modeling. Join my Discord for monthly discount coupons!
fantastic tutorial thankyou.
Is there an example on how to integrate with the gameplay ability system so we could use the input mapping classes instead of hard coded enum ones?
Yes, take my GAS course as I cover it
so basically when dealing with basic character movement/inputs dont do it in c++ instead use blueprints right?
Godly tutorial. Thank you very much!
I'm following a different tutorial, which had me set up a BasePawn then create a child C++ class from that, if anyone else is running into issues getting this to work using a child class, make sure that you have this in your header file
virtual void SetupPlayerInputComponent(class UInputComponent* PlayerInputComponent) override;
Was driving me crazy trying to figure out why it was saying that SetupPlayerComponent wasn't declared, this was why.
After finishing the tutorial only my A and D keys are triggering the UE Log. Can some explain how to fix this?
Amazing Tutorial, love you so much, you save me ;D
Hei man thankyou so so so much for this tutorial!
Thank you this helped me alot..
At 33:27 minutes in the "UE5 C++ Input - 2 - Bind C++ Functions to Input Actions" UTube video when I try to rebuild missing Slash modules, I get the message:
Slash could not be compiled. Try rebuilding from source code manually.
I fear I have lost everything,
Please help
Wade
Try opening the Visual Studio solution and building the project from there. If that doesn’t work try clearing the derived files like this…
Close Unreal and Visual Studio
Delete the following folders: Binaries, Build, Intermediate, Saved
Delete the Visual Studio or Xcode solution file (.sln or .xcodeproj)
Re-open Unreal
Good luck!
also, check your code doesn't have any errors.
I'm having trouble following along with the course.
How do i know, when i have to include it into Build.cs file? Sometimes you put the import directly into .cpp file, sometimes you just import the class into the .h file.
I can't find a consistency yet, on when to do what.
I don't get why would we still need to BindAction for each IA_Action in cpp. What is the point of setting up Mapping Context which should be used to manage all IA_Actions already? What would happen if we don't setup mapping context in BeginPlay, and only setup BindAction in SetupPlayerInputComponent and write our own custom functions for each action?
Same question
Welp, deleting all those folders completely fucked my UE5 project.
When I delete the folders and click on generate the project it stops working and no matter how many times I do it it does not recognize the files or it simply fails to compile
can someone explain why are we using a cast here @22:30
One last thing ive learned from this is... almost always, its just easier to use blueprints lol. We set this up in blueprints in like 30 seconds. It took 30 minutes to do it in c++. Whats the benefit of doing it in c++ over just doing it in bp?
that's an abroad question, not a specific question to this tutorial
It is a question regarding THIS tutorial. In this tutorial we did it with blueprints and c++, and im asking if it only takes a few seconds to do in bp's, at what point would you just do it in blueprints? Thats not only relevant to this tutorial, but the entire course.
@@ChristopherFranko I don't agree, but answering to your question in that specific context (that can be extended to all the engine), if you want for example bind a custom function in C++ with the control (for example a C++ class of a weapon that fires when a control is pressed), is much easier bind an event to that C++ class from another C++ class, that trying to get the class from the BP. You can finish the tutorial with BP in a few seconds, and you can finish the tutorial in 0 seconds if you get the template in BP because it's already done. It all depends on the complexity that you want to get in the project. If you don't like C++ at all, you can still develop a decent videogame just with Blueprints.
I was looking for an answer to a similar question and found this. ArcainOne's comment from UE's Forum on this subject: (I just fixed the grammar errors.)
If you are making any sort of game you plan to release into the world then C++ is for your CORE gameplay systems and Blueprint is for Designers to build out your worlds. You build an Inventory system in C++, but each item is created and defined in Blueprint. You can even do some basic enhancements or elaborations to systems such as altering your inventory system to also be an Equipment system in Blueprint, they share similar functionality and code but are still quite different. User Widgets I like to implement functionality in C++ and then re-parent the Blueprint Widget to it so my functionality remains the same. However, I can have several different appearances of the same object the widget represents. So you could have one Inventory Widget that is a list, while another can utilize the exact same C++ functionality but appear as a grid.
If you are building out a portfolio of games to show to prospective employers, then building out the gameplay in Blueprints is fine. But there is a slue of issues in using pure blueprints to build out a game you are trying to sell or distribute. Over time your Primary Blueprint classes WILL become bloated and take longer and longer to compile, transferring them to C++ will drastically improve that compile time. Blueprints will also LOAD EVERYTHING you have associated with them unless you are VERY careful to use Soft Object References and Interfaces wisely other wise it is very easy to accidentally load every asset of your game into memory on startup simply because you have a property reference to another class that references some assets and that class then references some other class that has some other assets etc. Finally, C++ is so much easier to debug so long as you are running in “DebugGame Editor” Mode which is unoptimized and allows you to step through nearly every function and view most properties; While blueprint can do some debugging it is nowhere near as powerful as good old fashioned code debugging, and you will become very frustrated at the phrase “variable out of scope” when you try to break on a blueprint node to inspect the value coming out of it.
@@brk29 Dude TY so much for this reply because its exactly what i was looking for.
I seem to be getting an issue, not sure if i should even consider it as an issue. When I did it via blueprints the show debug command was showing the input mappings, but when I did it via c++ it was not even though the output log was showing the message.
Should I ignore this "issue"?
"we cannot forward declare something that is not a pointer."
That is incorrect. Pointers, but also references can be forward declared.
Yes, I misspoke, references can be forward declared too.
Just like to add, in 5.3 i typed showdebug en and thought it auto filled. It didnt. It showed some of the debug but not the full context until I selected the suggestion for the full showdebug enhancedinput.
Other than Compile time is there any other reasons to forward declare?
Nice tutorial! But I'm being stucked where even though I've followed all the steps (I think?), the function coded in the C++ files attached to the blueprint won't be executed!
Another question : even the Input actions won't appear in the blueprint despite keeping opened the code solution and restarting Unreal Engine.
Do you know how to solve those two issues?
Thank you :)
I don't think that declaring pointers in "if" statements is just about performance. There's also a safety concern there - outside of the "if" statement, if you use the pointer, it might be null. By declaring the pointer in the "if" statement, you ensure that it's never used if it's null.
Great video. In UE5.3 I can no longer get the console debug command to work is this a bug?
Around 21:20 you said you already explained why we should forward declare over including headers in other header files if we could help it.
I must have missed that part and not sure where it is in the video.
Can your or someone else explain to me why forward declaration is preferable over including?
I'm no expert and while I'm sure this is somewhat the truth, it's possible I'm missing some points. Regardless, I'll try to explain. In this case, if you include something in Bird.h, then anything that includes Bird.h will inherit these includes, making a large chain of includes that can cripple compile times. That is why you want to make your includes in Bird.cpp. When something includes Bird.h, it will not include any of the includes from Bird.cpp, thus you won't get large compile times. So, when you need something like this, you forward declare it in the header if you need it, and you include it in the .cpp.
header files are made to be included in other files, but dont actually need to know how the functions of a class are defined, whereas the cpp does need to know. the general idea is to include code(in this case the .h) only where it is needed. if you link up a bunch of header files, one header for example could bring a whole bunch of other class headers along with it where they are not needed, that could increase compile times. forward declare avoids that by only having the specific .h where it is actually being used
Recently I have been having issues when I delete the binaries, saved and intermediate, then generate VS files and rebuild. I never used to have trouble during this process, if anyone knows why this might be happening I'd love some insight. Most errors messages I see in the output log are things along the lines of files not existing for the project but they disappear from the output log too quickly to get a pic or to copy them down. Although I did recently get a console popup as well that says Unreal Engine was exiting with code 1.
if I didnt want to use the property modifier 'EditAnywhere' and instead hard code this into the CPP file, would that be possible and if so how?
In Unity - how use input - answer use if(GetKeyDown). In UE how use input - look we have 3 hours tutorial.
We don't really do it that way in Unreal
Good tutorial, but to heavy on basic C++ programming. Templates, scope and so on should be known if someone wants to use C++ for Unreal Engine.
Why did you add `class UInputAction` instead of `#include UInputAction`? What is the difference??
It's a forward declaration. Learn about it in my UE5 course!
What do you do when BindAction doesn't accept the &MyClass::Move method and won't compile because of it?
Check to make sure your function has the right signature
What I need to do if every time I recompile, inputAction (like yours moveAction) resets in blueprint and I need to set again. How to fix that?
if you are Live Coding, the changes won't save. You have to save and close the UE Editor, build from your IDE, and then reopen the UE Project. You should see your changes now.
These 2 hr classes boi.. rough
Is there a reason as to why you aren't binding stuff in your controller rather than your character? Thanks in advance!
Nope! No reason
ur the beeeest
So is it more optimized when we change blueprints to c++?
C++ is strictly more optimal than BP. For setting up inputs it's not a huge difference in the big scheme of things.
@@DruidMechanicsGameDevelopment i see. One thing i wonder, when you are compiling it feels a bit slow, you know close project and open again etc. I wonder how we should approach this compiling process in a bit more complicated project. Say, i created a prototype project that includes advanced locomotion of a character, combat mechanics and AI only using BP scripting. How would you approach to turn that kind of project to c++?
@@canylmaz9730 Animations are typically handled in the anim BP (or now with motion matching) and it's not worth it coding that logic in C++. There's always a trade-off.
Hey! When I connect my Cast To Player Controller to Print String (to check if it's working) it fails.. Ie.. Only prints a string if I connect the 'cast failed' execution pin.
I'm working on the complete UE5 course and converting my bird pawn to the new system.. Do I need to remove any code?
Are you sure you are possessing the pawn? You can check Auto Possess Player.
You have to run in Selected Viewport instead of Simulate (option above the viewport)
Even if i had Auto Possess on Player0 on my pawn, it wouldn't possess it on start in Simulate mode, i don't know why. Since it doesn't possess it on startup, the cast doesn't work correctly
Hello Stephen! Is it required to update up to 5.1 release of engine?
Thanks!
It is not required. But you can! The engine has some improvements, including nanite for foliage!
I don't recommend 5.1 if you're using Steam Sockets
Do have Just a pure Blueprint class to offer? a 3d artist it is a little bit inconvenient for me to write code
Yes, and more UE5 Blueprint content coming soon!
Ot working for me to add enhanced input
Can't find the bird in the starter content
It's not in the starter content. The bird is from a free asset pack on the marketplace.
@@DruidMechanicsGameDevelopment ahaa, got it. Thanks!
34:29
ang hirap naman neto
this whole video could have been 10 minutes.
But you wouldn't have learned anything
@@Mittzys I would, matter of fact I would learn way better. Instead of wasting time around. I stopped watching and did myself.
@@jeffceff2821 You still had to learn it somewhere.
Getting a compile error after Binding the action on that line "'cannot convert from 'UInputAction *' to 'const FName'. Anyone else seen this?
*EDIT* User error - if anyone else is getting this issue, check you added the InputActionValue.h include to your header file @ 42:52
Couldn't successfully > the squiggles on #include are still there after rebuilding the project files and modifying Slash.Build.cs.
found the problem, I needed to write Subsystems.h, not Subsystem.h
@@mattipiirainen7440 OMG Thank you lol.
Thank you!
I love the detail you put in your lessons, thanks
It dawned on me! The default function "BindAction" passed in the signature "FEnhancedInputActionHandlerValuesSignature", so the callback function took the param "const FInputActionValue&"😅 I always thought that "BindAction" could only pass "VarTypes..."
Thanks!
34:27