Beginners Intro to UE5 - Create a Game in 3 Hours in Unreal Engine 5

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
hey everyone and welcome to this video today we'll be creating this simple rollable game we'll be trying to do this all in this single video so it may be a slightly longer topic than usual but i think we'll be able to get from an empty project to the final product by the end of this topic a few things to be aware of before we jump into this the topic we'll be using mostly c plus plus and we'll be doing this inside of the unreal engine 5. this is intended to get new people familiar to creating a very simple game in either unreal engine 4 or unreal engine 5 will be very very transferable a few things i wanted to mention just to set expectations first of all this is going to be aimed at beginners but i would expect you to understand some of the basics getting the engine installed working your way around the unreal interface and having a base understanding of programming such as variables classes types and things like that will be very very useful knowing some blueprint logic again will be very handy and because i want to get as much covered in as short a time as possible what i'll be doing is expecting some kind of self-learning along the way so i will pause every now and again and mention if i think something might be a learning opportunity then i'll mention that and it just means that you might need to pause the video research the topic that i'm currently discussing if it's not familiar to you and that means that the people that are familiar with these topics can follow along in a much more kind of smooth fashion and that way if you are slightly less experienced than the other people then that is your opportunity to go and browse the internet and i'll make sure that as i go through in the bottom left corner down here everything will always be getting a title when it's a completely new or when we're moving from one topic to another throughout the video so you'll have a reference as well of the kind of thing that you'll be looking to search on google to find those results if it doesn't make sense last couple of things i wanted to mention very quickly this will be a very high percentage of c plus plus pretty much as much as i think is required it will not be 100 c so for those of you who feel a little bit sick at the prospect of even dragging out a blueprint node apologies but uh there's some cases where we don't need to use c plus plus for everything slightly elitist and it just makes life much harder if you're trying to do a hundred percent of the project in c plus plus i'll be trying to show the process the best way to kind of balance blueprints and z plus plus there'll be sometimes where i want to extend things and i'll show you the best way to do that if you wanted to see more on this topic i have worked along with epic for the online learning portal the free courses they provide and i've created a balancing blueprints and a c plus plus in unreal so i'll link that below if you wanted to know more on that topic and another video which is really good in a more kind of theoretical way of where blueprints or c plus are best suited so i'll link both of those down below and finally i just wanted to mention as well that we're making a very simple game in this video so like i said i imagine it's going to be a couple of hours long i'm going to try and get as much as i can in this video as possible it doesn't mean we're going to go very simple but we will be creating all of the logic from scratch by ourselves what i mean by this is that there are classes and i'm answering this now because i imagine people will ask why haven't you used x so there are classes available inside of unreal such as the character class which would make the movement system infinitely easier than we're going to have in our project now the reason that we're going to be creating the simple rollable game is because that means that we can use the pawn class which has none of this kind of pre-coded stuff for us and i think this is much more useful for new people when they're looking at starting with an engine whilst the character class does do a lot for us because it is doing all of that for us kind of behind the scenes it means that the new people won't quite understand what's happening it's a little bit of programming magic you plug in a number and essentially you have a function which is called move character forward and the character moves forward but you don't quite know how or why so what we're going to be doing is we're going to take a step back from that a lot of other tutorials i've noticed we'll use the character as the default class and it doesn't really explain how or why it's moving so we're going to be looking at exactly how we're going to be moving our pawn and why that kind of logic is working to get it moving in that way and then i will say that these concepts are going to be very very basic we'll have just a few classes communicating with each other but i'm going to set this up in a way which really focuses on good programming practices as well so if you're getting started you'll be getting started in the right kind of way hello so quick insert here i'm about midway through recording and editing the content for this video and i've just discovered that another channel the unreal sensei has also released an unreal engine 5 beginner tutorial it's named the ue5 starter course you won't need to search for that again as with anything else that i've described or mentioned in this video i'll provide links for all of that in the description down below from what i've seen of that content again if you're completely new to development if you've never opened the unreal engine 4 or five before that content is around about five hours long so it's quite a chunk of information but he does go through absolutely everything so i'd recommend doing that one first if you're completely fresh you'll even get a tour around the very very basics like which button to press in the viewport um how to select items like the very very basics which is going to be very useful for some people as i've mentioned i have assumed some level of competence with the general editor or kind of interacting with an engine of some sort at some point to follow along with this video so if that isn't you if you do need the complete kind of tour as well then i would recommend that one again i'll link that in the description below it looks like some really good content so go and check that one out and then pop back over here to get started on the coding aspect of creating your first game inside of ue5 with c plus plus so that was it and i will just let myself continue with the rest of the video with that in mind if you wanted a little bit more information i do have a course i've released recently creating a very similar game it's all in blueprints but it does go into much more flexible larger systems which really help you understand how you can get multiple classes in bigger projects and creating an entire game all working together so do check that out if you wanted to know a little bit more about creating your very first game inside of unreal that course is now over 10 hours long so it has a lot more content than you'll get in here so hopefully there should be something interesting there as well okay so big introduction but we have a lot of things to go through and i just wanted to get the groundwork kind of out of the way now so you know what you're expecting what we're going to be doing and generally just trying to answer a lot of questions i think people might have had as there are a lot of different ways that i could have approached this so the first thing as i've mentioned you already have the unreal engine 5 installed so with that we're going to go to the new project creation page that should bring you here and what we're going to do is as i've mentioned create everything from scratch so a blank project all the way to that end working game that you've seen the best way is going to be from the games panel here we'll choose blank and then make sure that we have the target platform as desktop and the quality presets maximum should be fine for the name i'm just going to call mine yt underscore rollable for youtube underscore rollable you can call yours whatever you want you might want to remove the the youtube prefix there and then the first thing that might surprise you is that we're going to create this as a blueprint project not a c plus project and there's a couple of reasons for that and we'll get into that when we have the project created but i'd recommend following along with the base blueprint project for now so when you have everything set up like that we can hit create and let this create our new project for us when it's finished loading inside of the new project i'm not sure if you can hear in the background but my system's kind of the fan is going pretty heavy at the moment one way that you can address this is to turn off the real-time rendering so if we go to this drop-down panel just here we can see that we have the viewport options set to real time and that will also take up quite a lot of processing power so i'm going to turn that off which is why you'll see this throughout the rest of the video and if you could have heard it i'm not sure then you will now notice that the fans have died down a bit now another thing to note before we jump into the projects actually creating things for those of you with systems which may not quite be able to handle unreal engine 5 and i should mention as well you can follow all of this in unreal engine 4 all of this should work if you were just looking at getting started with either of the unreal versions regardless of whether that's in four or five but if you are on five and you wanted to try and save a little bit more performance again in a new project lumen is enabled by default so what we can do to address this is go to the project settings we're going to search in here for the global illumination and the first thing is to turn the dynamic global illumination method to none and then we can also turn off the reflections so again this will default to lumen and we can turn this to none and the final thing which people are reporting is causing a lot of a performance hit are the shadows so we've got this visual shadow map set to beta at the moment so again we can turn this back to the shadow maps and for most people apparently that will kind of get the performance much closer to what it was in the unreal engine 4. so if you weren't really interested we're definitely not going to be using the uh making the most of lumin and things like that in this video this is going to be very simple and based more around the code and the logic so if you were interested in the same sort of thing you wanted to use the unreal engine 5 but didn't quite have the kind of juicy system to do that then we can turn all of those down and this should hopefully get you somewhere with a more stable frame rate so with all of that said i just wanted to now explain why we're going to be creating this from a blueprint project and not a c plus project so first of all the shortcut i've just used there is controlling space to bring up the content drawer or you can just click on this to do the same thing now if we create this as a c plus project what that will do is it will create the whole sln system for us everything will be kind of ready to go and working which is good to begin with but it will create a game mode by default and it will prefix that with our project name then followed by game mode so we already have a class that we may or may not want with a name that i didn't really want to give it and it also just drops it in a very unorganized folder structure so i want full control over our folder structures our naming conventions and things like that so rather than trying to need to recompile things change names change locations we're just going to start with an empty project and we'll create our classes as and when we want them as we go through it's super simple to add a c plus class into our project anyway so that isn't going to be an issue okay so let's get started with this to create our first c plus plus class we're going to go to tools we're going to go new c plus plus and if you're using unreal engine 4 this should be under file and new c plus class i should also mention that i'm going to quickly go to my editor preferences a few things that we can change in here i'm going to change the asset editor open location so whenever we open a model or a blueprint i want that to be dropped up here in this top tab otherwise it will by default be dropped in this kind of floating window and i kind of hate that so we're going to drop this down to a main window and that means that now whenever i open a new window it will always dock it up here in the top tab the reason it's here though is i'm going to go to the source code option and in here you can see that i'm going to be using rider for unreal this now supports unreal engine 5 you can get this for free at the moment on the marketplace i would definitely recommend trying it out whilst it's free it's super fast it generally has a much better faster intellisense than visual studio provides by default and even compared to some of the paid extensions you can get for vs i would say that rider is definitely the better package if that's not available for you for whatever reason unreal engine 5 supports vs code vs 2019 and 17 so as long as you've got one of these installed and again i'm assuming you know how to get those installed then you'll be able to follow along just as well and you'll just need to check the i'll be describing any of the shortcuts and things that i use and most packages will have the same thing okay so back to creating our class we're going to go to tools new class and the first thing that we want let's get our player in the world and we can try and get that one moving around as i've mentioned we do have the character class which does provide a lot of useful functionality but i think as we're new to the engine we want to learn as much and understand as much of what our character is doing as possible so to get that kind of flexibility and freedom we're going to go for our pawn class for the naming convention here a lot of people tend to use the name of the project and then something like a pawn class or player class and i'm going to follow something fairly similar here now like i've mentioned i'm going to get rid of the yt underscore so i'm just going to call this rollerball and player i'm using the standard camel casing which is the starting the first word with an uppercase then the next word so ball would be also uppercase and then the final word again uppercase that's camel casing and that's generally again just a standard naming convention now the final reason i wanted to set this up with a custom c plus plus class and not allowing the project to do this by itself is we're going to take another step and this is that code folder structure that i mentioned where if we'd let the engine do it by itself it would have just dropped it straight into the rollable folder structure with no kind of class specific folders available so what we're going to do instead is we're going to create a new folder in here which we can do by just typing in a name here and it will automatically create that when we create our class and i'm going to call this one game so this is going to be all of our kind of game specific classes our player our game mode the potential widget that we'll add in so the things that are kind of a little bit too specific to have their own folder but they all kind of come together as the base requirements to have a game going now the reason i wanted to do this is that this will actually cause us a problem this is going to stop our code from compiling and i wanted to show you how to fix that because it's something which was prevalent in 4.25 i think and maybe 4.26 it's a little bit intimate and it seems to be an issue which comes and goes uh they'll fix it then it gets reintroduced and i figured it's going to be very useful for people to know how to fix this if you ever encounter it yourself it specifically comes from dropping things into folders but generally it's best to know how to fix this problem and organize things in folders otherwise you're gonna have hundreds of classes all in one generic folder so that's everything we need to do we will create this class we're going to expect that compilation error and then we're going to have a look at how we can fix this okay so when that's finished compiling as expected the class itself has been added successfully but it does say we need to recompile this to get the rollable class for the player to be recognized in the project so we can ask for more details but i know what the problem is i'm going to say no to this and if we have a look down here so control and space again to open the content drawer and if you did want this to be docked if you are not so worried about the kind of real estate back here we can dock this layout and that will have this kind of like unreal engine 4 if you are familiar with that what we hope to have seen would have been our c plus folder down here but like i mentioned we've got that issue i'm going to go and look at how to fix that name so the quickest way would be to go to our windows explorer folder for this project we can right click in the content folder and go to the show and explorer option this will give us our project in the windows explorer view and what we want to do we can see it's tried creating the sln down here so this is our code project that we'll be working from and we can also see that we've got the source folder now so we do have our class available to go we've got our game folder and in here the class that we've just created so it's kind of working it just has a syntax error which we're going to fix now so we can do that by opening our s1 again you're going to be doing this in either visual studio vs code or rider which is what i've got this to open with by default this is going to take a couple of minutes potentially to load everything and try and build the solution just so that we have all of the context sensitivity and all of that intellisense goodness we can see we have a bar down here syncing the project so yours is going to do something similar and i just recommend that you wait for that to happen before again we go to the next step of fixing our class okay mine's pretty much ready though so i'm just going to jump ahead a little bit with mine and i've pressed ctrl shift and b to try and build the project this is just again so that we can get an easy very quick kind of result here what the problem is actually trying to show us so the thing that we have being displayed is that we cannot open the file game forward slash rollerballplayer.h no such file or directory exists which we know it does because we've just created it now when we come in here again because rider has some pretty useful intellisense we can see immediately that the problem is this game folder this is like i said something which has been in older versions of the unreal engine this has been causing problems for quite a while not just in unreal five and basically there are two very simple ways we can fix this it's just a directory issue it doesn't know where this is the context that it wants to have is either the class directly so we can remove this and that would solve the problem you can see that fixes everything up or if you wanted to be very precise you could provide the entire path of the project so youtube underscore rollable and then forward slash and then the name of the folder and then forward slash again so that would also fix it it's just that it didn't know where that directory was because of the automatic naming convention now like i've mentioned i think personally it's a lot more useful to drop things into their folders it makes working with loads of different classes and bigger projects much much easier to navigate so i would say that knowing about this issue especially because it seems to come in and out of so many different version updates is going to be very useful which is why i wanted to take the opportunity as i've realized this still in unreal engine 5 to purposely have this happen and then we can fix it now so for this class it's going to be the only include that we need so i'm just going to go with the short form option so we're going to get rid of that and we'll just include the rollable.h and this is in the rollable player.cpp so the code file we can test now again i would recommend to let your files process but we don't need to do anything right now so i'm going to build this again with ctrl shift and b you can also go to build up here visual studio will have very similar options and shortcuts for you okay so that one has compiled successfully what will also happen now is if we go back to unreal we can see that down here we still don't have our code file so we're just going to need to close the project and we can now either build that through our ide so again ryder and vs both have this option we can change this to our project go into the development editor and we can run this so this will just open the project back for us and if you can this would be the way that i recommend working when in a c project or of course you can go back to your epic launcher and load the project that way the main thing is that when we open the project backup we now have our classes in the folder structure that we wanted and in unreal engine 5 we have the recompile for hot reloads down here in unreal engine 4 of course it will still be in the top panel okay so that technical issue that we're expecting out of the way we're now going to jump straight into the player code i'm going to set up the player components the things that we'll need to kind of build up the player such as the camera the the mesh and everything that it will consist of now just a heads up that because i realize that this text can be a little bit small for the rest of this what i'll be doing is i'm going to go into the view mode i'm going to go to appearance and i'm going to put this into presentation mode now that can make things a little bit confusing because the explorer to the side has gone but hopefully this is a little bit more viewable and just remember if you're wondering what class i'm in if you can see things like the rollerballplayer.h here that means we're in the code file and then what i'll be doing is i'm going to press ctrl o to navigate over to the header file which is where we'll be defining all of our variables the the meshes this is kind of like the location that we outline what the class will have so you'll see me toggling between them if you wanted to be in the same kind of viewport if you like this kind of view and again i'll try to make it clear which file i'm in as i go through but i think this is just going to make things a lot more viewable for people so the first thing that i know for our player class is that we're going to be driving all of the movement directly through the input bindings that we'll be creating later which means we won't need to do any updates on the event tick so i'm just going to remove this straight away and then the things i know we will need which are going to be those components the visual aspects and everything i've just mentioned i'm going to put in the protected section down here we won't need these to be public and these are going to be the components i'll be working with so the first one we have a u static mesh component named mesh this will be our visual aspect for the player that's going to be our ball mesh in this instance then we have a u springarm component named springarm and a camera component named camera now you can see immediately we have a problem here that is saying that it doesn't know essentially what these classes are and that's because there's no context we're using and include what you use system so we won't have kind of access or knowledge of all of the other classes in the in the engine which means we can just forward declare these up here so again this might be one of those first things if you're new to the system or c plus or this kind of coding then you may want to look into what forward declaration is versus the include system that we have just up here in short the ford declaration is just a little bit cheaper a little bit more lightweight and it means that we only need it will just give us the context of what the classes that we want down here are so we're first going to forward declare the uspringarm component and then the u camera component as soon as we do that you can see that the text for both of these components return from red to this gray color which means that that for declarations work so now this part of our code understands the context of what these components are then you will notice that for all of our properties the the components we have these with a u property above them i've set this to be visible anywhere a blueprint read only and i've put them in a category named component so another learning point here these are the u properties and meta specifiers if you wanted to look a little bit more into those but what they're doing is we have a system provided by unreal which will allow us to define specific behaviors for different things in our c plus class to direct them to behave or appear in a certain way in our blueprint class so what i've done here is we've made our meshes and components visible anywhere so this is in relation to the different viewports around the unreal engine we have this as blueprint only and this is very important because these are pointers to variables of these components we want to make sure that there is as little access or overriding of these as possible but we do want that visibility in our viewports and the inside of the editor in comparison i'm going to add some variables just below this i've got a float for the movement force that we'll be applying i've set this to a default of 500 units i have a flight for the jump force which i've set to 1000 which i think actually might be a little bit high so i'm going to set this down to 500 as well and the maximum jump count which i've set to a value of 1 which is an int 32 so we'll be using these the movement force will be directing or driving how fast we can push our ball around the jump impulse will be applying that certain impulse when we want the ball to jump around and the jump count is going to be because otherwise we would be able to jump indefinitely so we're going to have to implement some logic to make sure that we can only jump once until we've hit the ground now the u property for these you can see that i've set these to be edit anywhere rather than visible anywhere which means wherever we see this in the editor whether that's in our blueprint or the different browsers it means that we can update this so we can very easily in our blueprints change the movement force the jump count so we can add in things like double jumps if we wanted to and then i've made these to be blueprint read write as well and because these aren't pointers the same way that the components were that means we get that flexibility that we can make this read writable so that in our blueprint class we can check we can use getter functions to check what the force is and if we wanted to override the force or the jump count again we can do that in blueprints and the last few things we'll do whilst we're still in this class we need to make some changes over in the editor soon after we compile this but i'm going to add three functions in they're all type of void and these are going to be the move right function the move forward function and the jump function now all of these will be where we place our logic for the movement code the move right and move forward are going to take a float value as a signature or function argument and this is going to relate to the button being pressed is basically going to return which version of the button is being pressed whether the value will either be between a range of minus one zero or one so if nothing is pressed that will always be returning zero if forward is pressed will be so for instance move forward w would be forward that would return one and if backwards is pressed so s it will return minus one and that's how we're going to be driving the movement the logic in short is basically going to be this value the move force multiplied by the move direction value so if we wanted to move forward we're going to multiply 500 by 1 which will give us a positive value to move 500 units over a given amount of time and vice versa if we're pressing s then it's going to be 500 times -1 which will be a negative value of 500 units to move over a given amount of time jump doesn't need this because this is just going to be applying a force when a set button is pressed it's not going to be held it doesn't need to check the value it's either pressed or not pressed and then down here we have a new private section so again you may want to look into the difference between private public and protected if you're not familiar with these different sections that you can create in your code but this basically means that this value because we don't need to expose or call this anywhere else we can put these in the private section to make sure that there's no interference from outside classes and in fact with that in mind we could do the same with our functions these are only going to be used internally and we don't have any child classes so the protected section won't be relevant for these so we can put the functions down here as well and that means that nothing else can access the variables or functions in our private section apart from the class they're defined in the jump count is going to be working again it's an int 32 and this is going to be what we'll be updating to track how many times we've jumped and we'll be comparing this against the maximum jump count now the last few things that we need to do we want all of these functions to exist in our code file again ryder has a nice shortcut for this so it's alt and insert which gives us the option to create our definitions so we've declared them in the header we want to define them in the code file and what we can do here is we can tick all of them these three new functions i've created and we can press ok to allow this to automatically define them in our code file so this will automatically kind of hop us over there and we now have our three functions implemented now if you don't have those shortcuts i'm going to run through this anyway but i just figured that was a nice to know if you are using rider again it has these very useful features now creating a function is very easy in c plus you basically need to remember to include your function type which we've said is void because we're not returning any type of value this is just running logic and then leaving the function next you include the name of your class which is a so we've this is a type of actor or derives from the type of actor so we have a followed by the name that we've given the class which in this case was rollerball player okay so a quick pause here i'm just going through the editing process and i noticed that in a moment i say one word quite a lot when i mean another so i'm going to be talking about operators but i keep calling them accesses just a quick overview of why this is it's basically those little symbols that we'll be seeing the dot operator the arrow operator and the colon operator i kind of explain what they do and the reason i call them accessors is a very kind of intuitive thing that when you use them so in their context they're used to access other variables or functions within a class or structure or something so this is why i keep saying accessor they do technically access other things but it's very important that when you are learning about them and especially as i mentioned there's a kind of learning opportunity in a moment to go away and look a little bit more into the topic it's obviously going to be very important that you know that you're going to be wanting to look for something like c plus plus operators or the arrow operator and so on so just keep that in mind when i say accessor it is describes more of what they do but the actual terminology they're called operators we then use the pair of double colons which is an accessor so again a learning moment here if you wanted to pause and go away and look at the c plus accessor types you have three different types we've got the dot accessor period accessor i suppose the arrow accessory i think most people call this and the one i've just discussed here the double colons uh in short this is just going to depend uh you'll see that things that we're accessing from within this class or class that we are deriving from is the colon you can see the other things we've got the dot here and then the references the arrow but again if you needed to know a little bit more about these then it is something worthwhile taking a little bit of time and researching into that so it really makes sense but to create the function all we need to do is use the colon accessor here followed by the name of the function and then remember the argument or signature that we're passing in which for these two were the flight values so this just corresponds to what we had in here and then for jump there was nothing now another way that you can do this is basically copy everything apart from the semicolon just here we can copy this over go back into the code file and what a lot of people do if you don't have these shortcuts is just type uh paste these in and then before the void remember to add your player class and then add in those double colons and finish this off with a pair of parentheses so that's as difficult as it can be to add a function if you need to do it manually okay and you can probably see the final thing up here is we have our squiggly line because we've removed the declaration from the header file we also need to remember to remove the definition from the code file for the event tick and that means that we can also set the primary actor can tick to false as we won't need this class to run any kind of tick events to save a little bit of performance now one thing which is really important to be aware of when you're starting is at the moment we have again we've declared that we have some components and things in our header file but we haven't done anything with these so if we compile this at the moment and try and look at these in the the player class they won't exist what we want to do we also want to define what these are and essentially create them so i have a block of code here that i'm going to run through again i'm not going to type this out i'll just go through this hopefully this is more useful i can go through this line by line and tell you what they are that way you've got everything on screen and you can kind of follow along if you know a little bit of the concept behind these so for the components the first thing that we want to do is to create the three components that we had so we've got the mesh the spring arm and the camera all of these are created in a very similar way so we're going to use the create default sub object off and then we're going to pass in the type of object we're creating so for the mesh that's a u static mesh component for the spring arm it's a u spring arm component and for the camera it's the u camera component then inside of the brackets here we're just giving it a name so again i'm going to name the mesh mesh spring arm spring arm and camera camera and that is pretty much it now we can see here we've got the red squigglies which similar to in the header file means that we didn't have access to the springarm component we can easily fix this by going up to our includes here and the files that we want to include for the springarm component is going to be game framework forward slash springarm component.h and for the camera is going to be camera forward slash cameracomponent.h so this is the location in the unreal library that these classes are defined and then that means that we can pull in that information that library of information into this class so that if we ever need to access a function or a property of these classes then our own custom class now has full context of what that is now this is important because that's the main difference between a forward declaration and an include is that the forward declaration tells us what the thing is but it doesn't give us access to any of its functionality or variables the full include path that we have here will allow us to do things like setting functions or variables on other components or classes that we're referencing and as i mentioned with the ford declaration that's why the forward declaration is cheaper and is pretty much ideal in the headers because notice that we're not setting anything here we're not calling any of the functions or variables we just need to know what it is in our header in comparison in the code files you tend to use the includes because you'll see down here we are calling functions uh like the camera setup attachment function so we will need to have access to that extra information so the next steps we now have our components all created they're still not doing anything and we need to consider the hierarchy of these scene components they all derive from scene components which means they can have a transform or a location in the world and also relative to our player actor class so the first thing we want to do is set up the root component now this is a default understood thing in all classes that derive from actors we'll have a component which is expected to be the root component and this will make a little bit more sense when we see it in the blueprint but we're basically going to say that our mesh will be the root component so the top component in that hierarchy then next we're going to get the spring um and we're going to use the setup attachment function and we're basically saying that we want you to attach yourself to the mesh another way that we could have done this because we now know exactly what our root component is we could also say set up attachment to the root component either of these will work and do exactly the same thing one thing i would say is that it's going to be a lot clearer if we just use mesh like so it means that we're never going to forget what the root component is or need to double check what we're referring to we'll know that we're setting this up to attach to the mesh then likewise we're going to set the camera i'm going to tell it to set up again set its attachment so attach itself to the spring arm and the way that this will work is basically the spring arm will follow wherever the mesh goes it will follow the rotation in the movement and then the camera will follow wherever the spring arm goes it's kind of like a big boom stick so we can set how far away from the mesh we want the camera to be using that spring arm attachment and it means we never need to apply any offsets or rotations or anything to the camera to avoid any weird behavior with that done we can hit control shift and b or find your build option inside of your ide of choice this is going to compile everything and then that means this should be ready to look at inside of our editor and we can start looking at how this is going to be implemented in our blueprint class one thing to mention while this is compiling in the background if you're ever wondering how you know the kind of locations and the things that you need to include now part of this will come from memory once you've done it enough times i now know just from that kind of uh muscle memory i suppose that i've included the camera class so many times i know that it's in the camera forward slash camera component location now if you weren't aware of that again if this is your first time this is where you want to get very familiar with googling and using that kind of making sure you're using the search algorithm correctly so the easiest thing to do here is making use of the unreal naming convention if you search for something like you camera component or you springarm component that is so specific and unique to the unreal engine that it almost guarantees that google will return information purely on the c plus version of the camera component so as an example here i'm just going to go into google i've googled just this no other context no other information and i'm in a private browser with no history so that there's no kind of skewing of what's being returned based on my previous search history so as a first person potentially looking for this type of thing on a fresh system the first thing we can see here is we've got the you camera component documentation so if we click into this this is pretty much what we're looking for like i've said making sure that we keep the search nice and simple and to the point gives us exactly what we're looking for first time then straight away what we can see here is the important information is quite nicely put right at the top of the documentation page so if you needed to include this class then we just use the include for camera forward slash camera component.h so that's all you need to do if you're trying to add something new if you want to choose a different component like a collider or something and you're wondering how you would know where this information is just google it nice and simple uh google is a developer's best friend so another example i'll show the whole process here we're just going to go back into the code we'll get the use springarm component this time head straight back over to google paste this in again no extra syntax no need for what is the include for the spring arm in unreal engine 4. that's far too long that complicates things i think that's why people get stuck googling things is that they try to give it full sentences and loads of information keep it nice and simple we've got the unreal name and convention which means absolutely nothing else is using use springarm component that's not going to be a unity or a godot type thing so you're going to get directed straight to the unreal engine documentation and we can see here we've got the game framework springarm component.h which if we head back on over to our code we can see is exactly what we have just here so it's not just um a lot of things isn't going to come down to memory there are still components that i forget where they are so quick google search will kind of give you that information that you need straight away so don't get too daunted by this type of thing and again if you want to know more about any of what these are and this is what i meant by taking those learning moments those learning opportunities to pause the video and go and google something if you weren't aware of how to attach one component to another then again just searching something like unreal c plus attach component will pretty much guarantee to give you something like this so again nice and simple kind of broken sentence but we can see that first things we're getting are along the lines of the stuff that we probably want to give a try and test out inside of our code again some things won't work straight away but we can see component two whatever that is setup attachment to component one so nice and simple the first thing here is again just purely by chance exactly what we're looking for and i mentioned this because i get a lot of questions which i'm always happy to try and help with but a lot of questions which are so simple to answer if you just googled something and i've got people which will wait like a day or two for my feedback if i don't always see a message and still be stuck on it and i just think you could have googled that within a minute or two and had your answer rather than waiting for these two days um just getting familiar with something like simple search results like this can really speed up your development process okay so when i back in the unreal engine we're going to get to the good bits now we can start seeing our class a little bit in action it's not going to work yet but we can see the components we can start adding things to visualize it and see some of the progress that we've made first we're going to do this i'm going to set again the folder structure to be nice and tidy i'll create a new folder inside of the content folder here named blueprints and then another folder inside of blueprints named game so this matches our c plus code structure the shortcut if you're not aware is ctrl shift n to create a new folder or you can right click and select new folder from the option the reason we have this is we're now going to go to our code folder named game we're going to go to our player class that we've created we'll right click on this and select create blueprint from class now what this will do is this will give us a new blueprint class based on the c plus plus it's going to inherit all of those components and the variables that we've already defined i'll rename this to bp underscore player and i'll place this into the blueprints folder and then the games folder within that and again just a little bit of naming convention there so for blueprints you've got bp for blueprint and then underscore followed by the name of the class you may be tempted to do things in lowercase or just ignore it all together i would recommend is kind of a standard which is adopted by most developers and unreal now definitely in teams when you're working in bigger teams if you ever wanted to put things on the marketplace again this is all required and it will be declined if things aren't named this way so get used to that structure now it will save you a lot of time in the future so my system just completely crashed nothing to do with unreal your project should be fine i've been having issues with obs i mentioned that because if anything that i do now is slightly different then i was going to mention it a bit later but there are things which when you compile them inside of your ide and open things up for the first time inside of unreal some things don't always carry over usually that's fixed by a restart and that's why i mention it is that i've now had to restart my project where you haven't which might mean that some things haven't synced up for example you may select one of the components we've just created and it may not show anything if that's the case your code is probably fine there are only two steps we can either try to do a compile down here so recompile it in the engine that will normally work pretty much immediately and then if that still doesn't work that means that the things haven't synced up which is what i wanted to mention a bit later and you'll need to restart your project it's very standard it's a workflow that is annoying but you get used to when working with c plus and like i've mentioned it's one of the reasons that i've tried avoiding that c plus elitist mindset is because it really can slow the project down for no real performance or user case benefits and it just makes things harder for us with all of that said hopefully yours will look the same as mine i think at this stage we shouldn't have needed to have restarted the project anyway now what i was going to say we've just touched on the naming conventions so hopefully yours is named similarly what we can do now is set up our components so we can see if we go to the viewport we currently are unable to see anything apart from the camera the camera of course is already kind of pre-built but we don't have a mesh for a player now i'm not going to go ahead and import loads of fancy assets and things for this we don't need to worry about animations that's been covered in loads of different places we just want to get a nice fun playable game working now rather than importing things into the project a nice simple way we can do this especially for creating templates and prototypes we can use the drop down here for the static mesh we can go to this small options or settings icon and in here we want to take the show engine content this is going to give us loads of information loads of different things which are kind of pre-built and come by default with the engine the widget shapes you may be familiar with the cubes the spheres everything you kind of see is held obviously in the source content somewhere we can make use of this by searching for a sphere and be careful here you there are actually a lot of different types of spheres in the unreal engine we want to avoid all of the things like the editors and the sky sphere we can see if we highlight over this the approximate size of this is 320 by 320 which is huge the standard cube is 100 units which are 100 centimeters and we want something much closer to that size so what we're going to do is scroll all the way down we've got a few options down here and we want to highlight over them until we see the one which i found just here which is 100 by 100. so we're going to select this and that's roughly the size i wanted that to be so that's perfectly fine we can then make some adjustments so this is going to be a little bit closer for the viewport we're going to be looking through this camera in the game so we're going to get the spring on and we can move this back so if we grab our spring arm component that we've created we're going to grab this and we'll set this to something like 1000 so like i said is a nice easy way to control the camera so that's now 1000 units away from the player and it means that if we wanted that to be looking at a different direction we can rotate the spring on rather than the camera and this is what i meant by the hierarchy so the root component is now the mesh which remember we've attached the spring arm to and then we've attached the camera to the spring arm so all of those are taking those transforms of the component they're attached to so i think a viewport like this is going to be perfectly fine to look at the the meshes we go through towards the end of the video we'll look at adding some kind of niceties like materials and things but we really want to just get this moving and working in the project for now so i think that is a perfectly good start and we will work with this as we have it we can tweak the camera angles the spring arm lengths and things when we're in game and we have some of that uh stuff set up and ready to play with and the final thing i just wanted to mention again people completely new to the engine if you're working with other classes and this is something very very common with things like the character class people get very confused with what this inherited means and why you cannot remove you'll notice we can't delete the different components when they say they're inherited and this means that it's been defined in our code file our c plus class and anything which is defined or declared in the c plus code isn't able to be removed from the blueprint class and it doesn't just relate to c plus plus the blueprints also if you created a blueprint class as a parent of another and the child blueprint class had some components inherited from the parent you wouldn't be able to remove those either so i'm just going to compile that to make sure that we have that compiled and saved i'm going to head over to the project settings if you remember that in our c plus plus code we have created and kind of implemented already some of our functions for the movement but we don't have anything yet to bind to this so what we want to do is we want our axis mappings for the movement and our action mapping for the jump so if we start with the jumper first of all this is going to be nice and simple we'll create an action mapping here by adding the plus icon and what we want to do we need to make sure that this is named as something kind of logical it doesn't need to match the functions that we've created though if they do match the function names that is purely happenstance and you'll see that happen quite a lot in a lot of the existing projects then with our jump named what i'm going to do is we're going to add a first input binding which will be the spacebar so space on the keyboard to jump and the nice thing about these is we can add another binding here and we can also do things like uh adding a gamepad input so for gamepad i'm going to use the face button bottom which is the uh if you imagine on the gamepad the bottom one on the right hand side so that's either going to be a on the xbox x on playstation and however nintendo set those up probably b i think because it's backwards and you could of course extend this to other buttons as well having things like the up arrow to jump or whatever you wanted this is pretty much endless and it means that any of these which are captured by the controller when we're in game mode when we assign these to our functions any one of these buttons will trigger that jump function when we've made that binding now the next thing is we're going to want to add our axis mappings so again very similar i'm going to add a new mapping here the first one will be for move forward and as soon as we've named that we have an option to add our first binding now i'm going to create three of these and you'll see why and you can again add as many as you wanted but the three that i'll be using i'm going to be using wasd for movement you could add another two if you wanted the arrow keys as well and for moving forward so w is forward i'm going to set s to be back and then i'm also going to account for the gamepad now this time is a little bit different what we're going to look for is the left thumbstick and this will actually control forward and backwards and i've forwarded on the thumbstick y is essentially we're looking at up and down x is side to side so for move forward we're going to want the left thumb stick y axis now the one thing we're going to have to change here is s the scale will be minus 1. and the way that this is working if we can try and kind of visualize this is when we press w like i mentioned when we look at the code we're passing in that float value now what we'll be doing when we create our bindings w will be bound to the move forward and that float value will change depending on the button that we're pressing so if we're pressing w then we're going to be passing in one to that float value if we're pressing the s then we'll be passing in minus one again if we're pressing nothing we pass in zero and then the kind of unique one is the gamepad if the gamepad thumbstick isn't moved at all then again zero however if we push it kind of mid way forward because there's a unlike with the key presses there's some variation it's not always either zero or one so if we push the thumb stick halfway forward then we return 0.5 and again if we pull it halfway back we return minus 0.5 if we push it all the way forward then we're going to get that full one on the y-axis so hopefully that makes sense again i think it will make a lot more sense when we bind these up to our functions now in a similar way to our move forward we're going to want to do the same thing for move right so maybe pause the video here give yourself a small challenge you've got most of the answer on the screen but see if you can work out how you would implement the move right function so create a new axis mapping assign three or four different buttons depending on how many buttons or controllers you wanted to account for and give that one a go okay so hopefully nice and simple so what i've done is i've created a new axis mapping called move right again it doesn't need to be named anything particular but as long as it's very kind of sensible and makes sense what you've called it we will be needing these names a little bit later so do remember them i've then created three inputs similar to move forward this time i'm using d and a for the keyboard so like i said w a s and d d will be the positive so because we've called this moving right then the positive value will be when you move right so that's the one a will be the negative value so i've assigned this to -1 for a moving left and then remember it's the left thumbstick again but instead of the y-axis we're moving along the x-axis which is left and right unless you wanted to invert things then we're going to keep this as the positive value on the thumb sticks if you did want the inverse controls then you could easily set these to minus one and you would get that inverse axis mapping for the thumb stick input usually obviously not done for movement but you might want to have things like camera movements if you're that type of person we now have our input binding setup in the project of course this isn't actually bound to anything in our functionality or in our class and that will be the next step a quick learning moment for you if you wanted a little bit more context on this between the difference between action mappings and access mappings again i can give you very short form answer here but action mappings are generally for things that you do once so things like jumping you either press the button or you don't and you'll notice the main difference here is that these are generally mapped to things like buttons or your keys where again similar to the functionality they're either pressed or they're not in comparison access mappings can be held down that they're accounted for over the time in the functions in which they're used they're kind of like an event tick they're constantly checking and updating and again there can be values between set ranges which is normally minus one and positive one zero will always be returned if the button or the in this case the analog stick isn't pressed at all or moved at all back in our code files the first thing we're going to look at is we're going to jump back into the header something i didn't touch on previously but which was here by default in the pawn class is that we have the setup player input component now this comes with anything which is either a pawn or derives from that let's see a small typing issue there and what this means is that again if you're not familiar with the unreal class hierarchy most things derive from an object you then have actors which are the first type of class which can be placed in the level and then most again classes are derived from that because almost everything needs to be in a level or a map and the first class which derives from the actor which can be possessed is the type of pawn and then all of the more complex things like vehicles characters 2d characters are all derived from the pawn class so that is the first possessible class and all of those will always have the setup player input component so that we can grab that information from the player controller and process what happens with those input bindings so this is the function we already have we can use this immediately so i'm going to head over to the code file and go down to the player input component and this is where we make our bindings from what key is pressed or what button is pressed and what we want it to do when that is triggered or detected so we'll work through our code here again you can see we've got three different bindings i've pasted in and all of them mapped to the things we've just created so the first two you'll notice are the custom input axis bindings we've got the access binding for move forward and move right the way that we do this is we access the input component and then we call the function within that the bind axis and again just to recap hopefully you've taken a break and had a look at the access operators you'll notice again we're using the arrow because the input component which we're getting is a pointer so this is a pointer accessor that we're using just here and then the function that we're using so we're binding the axis for the move forward now this is very important the naming inside of this text bracket is the one which needs to match up exactly with how you've named things in your project settings input section so this actually is context and name sensitive so if you called this something like move forwards then that wouldn't work it wouldn't have an input to bind that to the next argument is the object so once we find this input the next thing is the object in which we want to bind this functionality to something so it doesn't always have to be the same class but it usually will be so in this case we're going to bind it to a function within this class so we're just saying this so the object context is a function that we've defined within this class and then the final thing is within this class then what function do we want to call when this binding is triggered or detected in this case it's going to be the a rollerball player we're using the ampersander here so make sure that you don't miss that one and again we're calling the function internally so we're using the double colons here and then accessing the move forward function so what this means is whenever we press this button again matching with the player setting spelling we're going to call our custom function move forward down here now remember this is the bit where this function doesn't need to match the the input name generally it does just out of habit but we could have called this one move player forward or something and as long as this bit down here match to move player forward then the move forward button would have called the move player forward function if that makes sense now the other thing is because this is an axis it's taken as a given that a float value of some sort is going to be passed across because remember we're going to hop back over to our project settings this is essentially a function parameter so we've got the name of our input what is being bound to and the parameter so it's a default sort of given that we need to account for a float value so although we're not passing anything just here you can see that the function is expecting a float so the float is actually going to come from the binding so again if we're moving pressing w this is where this is going to be set to one if we're pressing s this will be set to minus one so that was a little bit of a complex overview but it's exactly the same thing for move right so again we're binding the axis to the move right binding binding it to a function on this class and that function is the a-rollable player move right function now action mappings are a little bit different so this time we're going to use the input components and we're going to bind action so just the different context there so between the axis or the action then again we're going to make sure that we have this spout exactly the same as the input binding we've created in the project setting so jump the difference here is the first thing is we want to know what the event is the type of key event and we actually have a few of these so i'm going to copy this we won't be keeping this in but as an example so for the key event we can change this to ie and then underscore and we can see we've got access pressed released repeat some of these you i haven't seen used pretty much ever but um the ones you always see used are going to be pressed and released so generally you can do something when the jump is pressed and then you might want to do something when the jump is also released so when the key is back up now what this means is if you've got something like a variable jump height then when the key is released that's when you're going to stop the force being applied vertically so you can have a little bit more control over your player in a racing game it might be when you release it that's when you want to send that notification to kill the throttle or something so having this kind of pressed and released relationship and context can be very very useful now this is going to be super simple there's no jump height variables so we can just remove this one for now so the next thing we've got that down the main thing here is we want to make sure that when the button is pressed we want to again then just bind a function to somewhere within this class and that function is going to be the rollable player jump function so this one down here that is the bindings so we now have all of these inputs are bound to do something or call something when they are detected what we want to do is move down to our functions where this will be happening so if we start with none of these are really much easier than the others if we start with the move right i'm just going to paste in again some code that i have here now what we're going to do is on move right again i'll run through this everything's on screen so you can kind of absorb it but i'll run through it all so what we're going to do is we're going to create a new f vector i've said this to be constant just because this means that for as long as this is running the variable itself won't be the same obviously we're going to change what that variable is but it's constant in the sense that that memory allocation is always assigned for as long as we're running this we're always going to need a value called right so it's not going to be added to any garbage collection or removed or replaced is going to be in the same place in memory so that would be another learning moment if you wanted to go away and find out what constant values are there are two differences you have or two main different ones that you will find at least you've got runtime constant variables and global constant variables which act slightly differently for now though what we're going to have is our f vector named right now this is going to be the result of the camera function the get right vector on the camera now the reason for this is after some testing we could have done things like hard coding a vector so saying that right is always going to be zero comma one comma zero so it would look like this because remember that in unreal x is always forward y is always right so positive one on the y is going to be right and z is always up that doesn't look great it kind of looks like a magic number and in context that could always change now what i decided is it would be nice to use one of the components and find out where they're facing in the world now the problem is that with the mesh that's going to be rolling remember we're rollable project so the right and forward vectors are actually always changing which can give you some really bizarre quite funny results but remember the one important thing that i mentioned is that because we've got the camera on a spring on the camera's vectors never actually change so it's always going to be facing in a certain direction which means we can always find out relatively where a write is so what we're going to do is we're going to use that and we're going to get the right vector which is just a function call which will essentially after all of this it will just return positive one essentially on the y and then we're going to multiply this by our move force so remember our variable that we've created over here we've exposed this so we can change this at any time we're multiplying this by 500 and then we're multiplying this by a value so value is the value which is being passed in to the move right function which is based on which direction we're pressing so remember a little while back i said this is going to be either zero so to stop movement when nothing's pressed we're going to multiply move force by zero cancelling out everything when we press forward we're going to multiply it by one so we're going to move add 500 forces of unit there and when we press s to move back we'll multiply this by -1 so moving back in that force then finally now that we have our right vector so the amount of force that we want to apply in the right vector which is essentially going to be so we've got 0 1 0 is going to be the right vector multiplied by move force which is 500 multiplied by value which is either 1 0 or minus 1 so we then change that to zero comma either 500 or minus 500 comma zero so that's going to be our right movement we're going to take that value we'll call the add force function on our mesh and we're going to pass in the right value so we want to pass in 500s of force to the right vector of the mesh so again using some intellisense and playing around with the code a little bit this might be a nice time to pause the video and see if you can do the same thing for the move forward function it's all very very similar essentially just changing the name of the custom f vector that you're creating and then getting the right vector direction from the camera so i would pause that give that a go and see if you can do the same thing to get some forward movement implemented the results then basically we're going to create a new constant f vector again the rename is going to be forward just logical and this is going to be equal to the camera and this time we're going to use the get forward vector function so again all built in and what i meant by using the intellisense is if i delete this it's as simple as we know that we need something in the forward direction so if we type forward it's actually the only function that we can use so we're going to try the get forward vector and that is basically the result again we want to move forward based on our movement force and the key which is being pressed to finish this off because remember that at the moment this is just a vector if we didn't do this bit then nothing would be happening we're just creating a vector we want to then take that forward vector and add force in that direction to our mesh so if you kind of read it backwards as well it will kind of make sense on what we're doing so for the last one we have our jump function and our little bit of code here what we have is we again we're going to use our jump impulse so the variable that we've already exposed i remember how i said x is forward y is right and z is up so we're going to apply that impulse on the z axis to make us move upwards and the difference here is you'll see that the movement the move right and forward are using the add force function calls whereas the jumping is using the add impulse function call so that's then creating a custom vector within that function call on the mesh and we're setting the f vector to be based on the jump for us now the reason being is that the the two differences uh add force is accumulated over time so something like a rocket thruster or a physics-based rollable would be accumulating force as it moves whereas the impulse is just one usually bigger kind of initial boost of that force but then it's not applied again so once that unit of impulse has been applied essentially gravity is left to take over friction and so on so if we wanted to try this this would kind of work so i'm going to compile this now in the background i do know that a few things will go wrong here but again it's nice to have those kind of planned issues that we can fix and overcome as we see them the main things are going to be we're going to have some rotation issues with the camera or the spring arm specifically and the force is going to be a little bit uh too weak in this case we'll also be able to jump indefinitely because notice that we haven't made use of the jump counts or the maximum jump limit that we've we've that we've declared in our header but we haven't actually defined them or used them anywhere in the code file but that's fine sometimes it's nice to see what the issues are and it will make a little bit more sense why we're fixing them when we come back to these classes and go through that process with that compiled then back over in the editor there's a couple of things we'll need to do to possess our player now this isn't an ideal setup but we're going to fix this when we get a little bit further into creating another class the game mode a bit later but for now we're just going to drag and drop the player into the world and we want to scroll down with the selected to find the auto possess option so we can see here autopsy player is disabled because generally the project would like to manage that by what you set in the game mode and again we'll look at that a little bit later but for now we're just going to override this to say that because you're here we're going to be possessed by player 0 which means when i possess this and look through the camera and before we do that i just noticed we've left all of the extras here so we can come in tidy things up on these settings and untick the show engine content that bring us just back down to the folders and structures that we have in our project then if we press play we can give this a go okay so this actually provides us a couple of issues the first one i overlooked is that we're trying to apply force to something that doesn't have physics enabled so quite a simple one we're going to go into the player class we'll grab our mesh and we're going to go down to the physics option and tick the simulate physics if we hit compile we can try this again okay now this time if you've tried that it may look as though nothing's happening but that's because the force is incredibly low so the mesh is actually set by default to be i think is around about 100 kilograms 109 kilograms we're only applying 500 units of force over a very limited multiplied by very small numbers to get this working so this would actually need to be something like 500 000 maybe and something similar maybe 50 000 for the jump for us so if we come back in we should now have some movement and we can see the rotation issue that i mentioned so that may make people a little bit nauseous but we can see there is indeed movement and if we press space that may still be a little bit too low so we'll increase the jump impulse we're going to go back into the viewport and we'll try this one last time and as mentioned we can jump indefinitely we still have that rotating issue so the rotating issue can be fixed really easily from the player class just here we're going to go to the spring arm and what we want to do is we just want to make sure we do not inherit remember i said that the components will inherit all of the location and rotation of the parent components so we don't want that for the rotation the pitch you're in the roll so if we untick those that means the spring on when i follow the direction that the ball goes but it will always face directly in this position from the camera to the player so when we come back in we have something that looks a little bit more like this which is much much better back in the code file then we're going to start looking at some of our default properties that we should have set up to begin with and this kind of thing helps us with properties like the set simulate physics where it was pretty much a given that we needed that to be enabled to avoid other people that we're working with potentially designers or artists from needing to understand some of the core setup and having that kind of issue appear when you've made a push to the repository and made the updates we can set these to default to be set active in our code file so again any child class that ever derives from this again will automatically be set to account for physics the way that we can do this is really simple so in the constructor after we've set up all of our other components so that we know that they exist and they are in the correct hierarchy i'm going to get the mesh and the one thing that we know this will always need to do is simulate physics so i'm going to call the set simulate physics function and set that to be true by default which is the same thing that we've ticked in our blueprint version so pretty much anything that you see exposed in the blueprint you can always access those functions in your c-plus plus code as well the second thing then was going to be the amount of force that we need to apply to get the ball moving now we could leave it as we have it in the editor where we're adding hundreds of thousands of units of force to a lot of people that can look quite strange though and again we always want to try and as a programmer think of the kind of expectations of the end user the designer the the artist that might be playing around with this and if you don't provide a default value or you forget to input default value then they probably will think that something like several units or several hundred units of force are what they're looking for and if that doesn't work they may just assume it's broken it also makes it more kind of human readable and workable when we have more grounded and lower units of force that we need to play with so what i'm going to do is scroll down to the begin play and as soon as the game begins playing i'm just going to add an offset or a modifier to the values that we'll be working with now the easiest way is we have one value which is never going to change and if it does then that will kind of need to be accounted for in the force which is being applied anyway and that is the mass of the object so we can use the get mass function on the mesh component so again another built-in function which is simply returning the mass value that we saw in the editor so that 109 kilograms and what i'll do first of all is get the move force make that to be equal to the move force multiplied by the mass so this is at the moment saying we'll make the move force equal to 500 times 109 we'll just round that down to 100 making it that 50 000 units of force then very similar the jump impulse is doing the same thing i've just provided a shorthand version of the same equation so again just to get you familiar with how you may see both of these mathematical operations approached so this is saying jump impulse times equals the mesh dot get mass so this is again when we see the operator here times equals or plus equals that is basically saying take this so in the same way we're taking this here and multiply that against itself and add it against itself and the other thing so we could easily tidy this up and make this a lot shorter as well so i just wanted to show you that this is the same as this so what we're going to do is we'll remove that one and then we just flip this around the other way and we'll say that move force times equals mesh dot get mass as well and i'm saying dot but it's the access operator and then in the same way jumping pulse times equals mesh get mass so this is going to take our jumping pulse which is i think at the moment the same value multiply that again by the mass and then set the initial value that we are querying here to be the the result of this equation so that now means that as soon as we press play if we compile this we'll have these values ready to go in the editor so we will need to account for that in the editor but it does mean we can now work with these smaller values and i think in fact whilst we're here we could probably completely wrap up the player class and then we might not need to return to this again for the rest of this project so the final outstanding issue is going to be that when we jump we have that infinite amount of jumps that we can currently hit because we're not tracking the jump count or the maximum jump account so we can start looking at this in the jump function this is going to be really nice and simple to cap this at the very least it's going to be the resetting logic which turns out to be a little bit more difficult so in the jump function what i'm going to do right at the very top of the function so before we do anything else i'm going to say that if we have got the jump count is more than or equal to the maximum jump account which means we've hit that maximum number of times that we can jump then we're just going to return straight out of the function just going to do this in one line because it just for something this simple doesn't really need all of that extra space i'm gonna put a comment at the top there and then just below this what i'm gonna say something i've not mentioned in fact is the comments so i've just copied these in just so that you can read through and get an idea as i'm talking also what they're doing with a little bit more context it's just two two forward slashes and anything that you add two forward slashes to becomes a comment which basically means that the compiler will not acknowledge it when it goes through so it's not going to be added into your code it won't be added into your logic it's a way that you can just keep track and you tell other developers and yourself remind yourself kind of what the code was intended to do if it's slightly more complex generally things like this won't need a comment but again just for context whilst i'm doing things if you wanted to read through i've put comments here but i mean this sort of thing adding to the jump count is pretty obvious what it's doing and why but the final thing is that one step and that's going to be that if we haven't reached the maximum jump count so if this hasn't yet been uh hit for that maximum jump count limit then we're going to add our impulse so we're still going to do our jump and then we're going to add one to the tracked jump count so this would now work this would mean that we could only jump as many times as we've set this value to be the problem that some of you have probably seen is that we're not resetting this now so that means that once we've jumped even when we hit the floor we'll never be able to jump again so this is our last big task for the player what we want to do is we want to use some again input functionality which is going to be the hit event so when our player hits something we want to know about that information we want to find out which direction we've hit something preferably below us which means we've landed and then we want to reset our jump account when that's happened so it sounds like it could be quite a difficult process but it's actually going to be really simple and i'll show you how so the first thing that we need to know is that we can bind one function to another in the engine and what that means in this context is we're going to take the built in mesh collision function and whenever that's triggered we're going to bind it to our own custom function which will be the function we can place our custom logic to check that direction in which the hit has been received so the way that we do this is with a dynamic delegate binding it's very very simple so it can be a little bit daunting but once you know how it's super simple to do what we want to do is we want to first of all get the function that we want to bind to so that's going to be our mesh remember i said we're binding to a built-in function on our mesh and i'm going to type this one out as i go along because there's a few different steps and we're going to kind of break this down as we go along so the first thing is we're going to use the on component hit so we can see this already exists this is within the context of the mesh component or also actors have this or something very similar at least the actor hit and we have different options as well we have overlaps and we have hits so hits are the physical things so when we are blocked physically by something else that will be counted as a hit and we also have overlap so when we enter the space of another thing if we're not set to be blocked by it then that would be an overlap and we can use that for things like triggers so if you imagine like a checkpoint system you want to know when something goes through the checkpoint but you don't want them to be you usually don't want the player to be physically stopped so rather than using a hit you would use an overlap which means the system can tell that something's gone through but it won't physically stop them from progressing through a checkpoint in comparison when something is going to block like a wall then that's going to be a hit so you're going to get some information back that something's hit that wall in a certain place and that's what we're going to be using so now that we have our function we want to call something on this function so another built-in functionality here which is an add dynamic binding so we're going to say dot add dynamic and this is a function call so we'll use our brackets here and it has two things that we need to pass in now the first thing is just a context object so this is basically taking in those two parameters one is the location or the object space in which another function is going to be called so like we've seen with the input bindings this is very similar so the object context is going to be this because we want to call another function within this class and the function that we want to call we haven't yet created because we need a little bit of information about the function that we're binding to so we want to make sure that this function we're about to create that we're going to bind our custom functionality to has the same overrides or signature details as the function we're binding to so an easy way you can do this again this is available in visual studio you'll need to find the shortcuts or or the name of the functionality to do this but in rider we can right click on the on component hit we can go to show context actions and we can navigate to or alt plus not sure if that's the apostrophe and then we'll click that and we'll go to the declaration so this will take us to the class where this functions defined and give us some information about this now this isn't quite where we need to be so i'm going to control in f if we double click on this and ctrl f that will be the the functioning we're looking for and i'll go to the next instance where this is found within this class so what this will do it will take us to our delegate cast here and the important thing so we can see that this is on a u primitive component and it's the on component hit and then everything after this is what we want so this is the signature of the function call so it's a nice easy way to find the signature of a function call so once we have all of these we're going to need to tidy this up a little bit but i wanted to show you this process as it's going to be safer to copy and paste this and it is to try and copy it by hand it's going to be very easy to miss something so we're going to ignore the on component hit because that's the function everything after that is part of the signature when we have that we're just going to return to the class that we were in and we're going to want to jump over to the header so this will have an issue for now that's fine we're going to come back and finish this off but what we want to do is we can do this in the private section again nothing outside of this class will call this function it's going to be a void function as that's the same type that we will be binding to i'm going to call this one on hit you could call this custom on hit my on hit this can be called anything and then what we want to do is paste in the parameters that we've just copied we can see here we've got an issue where every other one of these is red and that is really handy inside of um ryder that this makes it very clear which commas we need to remove basically everything's been provided a comma and we want every other comma to be removed so if we take this one out that will fit the hit components what we're saying is we're defining a u primitive component pointer named hit component then next we want an a actor named other actor and so on so just removing every other comma to get rid of these red names when that's been done you can see we have our override name we need to close this off with semicolons and then that is everything as we need it for matching up with our binding so that's really the most difficult bit about when you're trying to bind one function to another is making sure you have the correct override it's always easier if you can find that from within the ide just because it means you're going to be the most up to date sometimes the documentation can be a little bit outdated or a little bit hard to use if you're trying to find it on like a q a page or something again they may be using an override from an older version and if that gets changed if another component is added or removed then your signature could be out of sync and you'll have compilation issues when you're trying to make those bindings so the final thing of course like with anything else we want to implement this so again if you have the shortcut alt and insert for rider to create a new definition because we only have that one available it will know that we need the definition for our on hit function and then the final thing is remember we want to we've defined that we're going to be assigning this to a function within this class we now know that that will be our on hit function so what we want to do is we're going to come up here and again very similar to the player controller bindings we want the address of our a rollable player and it can see here that the only thing that we can really validly assign this to is going to be the first one that comes up is our on hit function so double click that and then that is it we can close this off again similar to the bindings as well with the axis where we didn't need to specify we didn't have to put like a comma in to say that we'll be passing in a float to something it's just kind of a given that the value will be taken from this because an axis needs that float value in the same way here we don't need to account for the signatures here it knows that this function has a set number of signatures this one matches that so they will all be passed so when this is called for instance the on component hit like i said tracks things like the other actor that was hit the other component that was hit that's all basically going to be passed into our information here so the hit component other actor are all going to be passed along to each other so we can still use those in our own function and that's it so now as soon as anything hits our player or as soon as our player hits anything this function will be called internally and that is now linked to also call our version of that same functionality which means we can now come down here and we know that whenever that is called we can run our own logic to check where we've hit something and if it was below us that hasn't fully made sense yet we will be looking at more bindings in other classes throughout this uh this small course so don't worry too much is one of those things where repetition will definitely make this much much easier it will all become very much second nature so the final thing to get this player jump system and the landing system implemented is going to be calculating the hit location or the direction in which the hit has occurred again this might sound kind of daunting but it's really simple so let's take a look at the code what we're going to do we only have three or four lines of code here really depending on how you format it it could be two lines essentially with some comments so what we have we know that we only need one thing to be accounted for which is the z direction we've got all of our axes we understand x is forward y is right left z is up down so we don't need the whole hit information in fact we don't need a lot of the information we're passing in here we can see the only thing that we're going to take is the actual hit details which is a structure of information including things like the rotation that we've hit the thing the location that we've hit the name of it the materials that it's using has got a whole bunch of information it's very useful but we are literally going to take the hit.normal value and not even the whole normal value so the normal is an f vector the normal of which we in space that we've hit the other object and we don't even need the whole thing we need the z axis of the normal so we're going to create a new float it's telling me here that this can be a constant so again we're going to make another runtime constant just to tidy this up make it a little bit more performant um i've called this one hit direction and that's going to be equal to the hit.normal.zed so this is now our head direction very very simple all we need to do is we have the information this is basically going to be a value between -1 and 1. so if we jump up in the world and hit something above the ball's head then that would be minus one and if we hit something below so directly below us would be one anything kind of between zero and one to like 0.25 would be a slight kind of slope or it would have at least indicated that we've hit something on our mid to low side and so on so we can see here that if it's more than zero then we've hit something below us one is flat anything between is not necessarily a slope but like i've said it's hit us on a side somehow which means it's quite likely to be a slope so if that's the case if the hit direction is more than zero which means it's not hit as directly side on then what we want to do is we're going to reset the jump count to zero we're going to class anything more than zero as the ground which means we're being a little bit lenient we could potentially hit something fairly low but not directly blurs and count that as ground but that's perfectly fine for this type of game and we're going to reset the jump count to zero so now every time we jump we're accounting for how many times we've jumped up to our maximum jump count and then when we hit the floor again we're resetting that which means we can start using this again and repeating that cycle so that is 100 of the player class i can see that we're going to be implementing i don't think in the small game that i've got planned we should go any further than this so if you hit compile we can now go back over to the editor and we can try out all of our player systems and see how this is looking okay so mine has compiled we can now go into the play mode and again we're going to test this we'll see if everything's working i should be able to set here how many times want the player to jump i've set this to one so at the moment i should only be able to jump once in the air and not be able to jump again until i hit the floor one thing of course we're going to set the move and jump impulse back to 500 otherwise we're going to be setting 50 000 multiplied by 100 and we're going to get some pretty powerful moving forces okay so the movement worked there the jump did work it's been capped but it isn't being reset so we want to find out why that is now this might be one of those times where we need to restart the project i can see the other things have been accounted for so most of the code has worked we've defined a whole new function and bind that to something this is the type of thing that was c plus plus sometimes you will need to do a system restart we can try and recompile it and see if this will work usually i'm not sure that will and yeah so when i'm jumping that's still not working so that's fine we can work out what the problem is another thing that might be happening here is that we don't have the correct collision setup we're going to be looking more at collisions a bit later when we have other things to interact with but i think we've got the generate overlap events which is for like i've said checkpoints generally use overlaps we will need this later so we can leave this tip but we don't have the hit events and remember we're binding our function to an on component hit so we will need that one to be ticked so that might be all the problem is okay and that's still not working uh one thing i will check is we're going to come in and we'll change the jump count up to two so we'll see if at least we're tracking the numbers correctly okay so i can double jump but then it's still not resetting so this makes me think we've got an issue with the collisions um which like i've said that is fine it's going to be very easy to fix now because i think we will need to reset the project at some point anyway and i think this is one of those times you can see we're still inside of the untitled map which means we've made changes to this map but we haven't saved it anywhere so back in the content folder ctrl shift n to create a new folder name it maps and inside of here we'll just press control ns inside of the the viewport save our map into the maps folder and we'll name this one main now something very useful is if we go to the project settings because we're about to close the project we'll go to maps and modes we're going to go to the editor startup map and we're going to change this to main which means now when we close this and reopen the project rather than loading into the default kind of empty world project we'll load straight back in to this one so let's restart the project and i will see you back when we've done that okay so everything's open back up you might get some of these warnings you can dismiss these uh you can tell this to open things if you wanted to but i'll do that as and when needed and then we're pretty much back where we are i'm just going to get rid of this i don't really want that to be hanging around all the time and then we can come in and do our double jump we can land and kind of jump now no so we've still got an issue happening here now this wasn't actually planned i'm a little bit stumped on why this is happening but it does give me the opportunity we can go into a little bit of debugging which will be quite useful as well so if we just double check one more time we need to open up the full blueprint editor go into the mesh and again just really make sure we're getting the correct collisions because this really should be working we've got our bindings correct we've got the hit events being triggered and we're blocking absolutely everything so we can see that we're blocking everything we should always be getting the hit event a good way to test this is we can grab our component and remember the function that we're actually overriding or binding to is this one here the on component hit so i'm just going to drag a print string and check that it's working in the blueprint at least i mean because we're being blocked i'm pretty certain that the hit event should be getting fired because we have it ticked to fire when it happens and we're not falling through the world which means we are hitting and being blocked correctly so there we go we can see us printing which means the function is being called in blueprint but not c plus plus so let's hop back on over to our code and we'll take a look at this okay so the first place to check uh is going to be our header is it to do with where we put this i think the private section should be perfectly fine we've got the signatures that we need i can drop that down to make things a little bit tidier just so you can read it easily and i can see the problem okay so simple problem here whenever you're creating a function with the intention to bind it it needs to have some unreal boilerplate understanding of the macro system the macro system is basically the u functions so similar to what we've done with the u properties to make them an unreal property essentially we're making this an unreal function it means that things like the properties and components will be added to the standard garbage collection in things done by the engine and in a similar way we don't need to assign anything we don't need to provide any matter specifiers for this function but because it's being used for a binding i forgot to give it the u function which i think is enough to stop that working so we're going to compile this again it should be a quick compile now and then we should be able to test this back in the editor and in fact one thing that kind of took away from the opportunity to do some debugging so what i'll do is whilst we're back in the code what i think would be quite useful is we can find the value here so when we have this function working let's print the value of our hit normal so we can get a little bit of information so that i can kind of show a little bit more of what i meant about the kind of direction that we're going to get and a nice simple way to do this is to use the g-engine add-on screen debug message it takes in some overrides here so we're going to need a key just to make it a unique key of minus one the time in which to display on the screen so 15 seconds the color to print this i think the background is a little bit bright i think i might change this to something like an orange and then the f string print printf and the text that we want to print in here so it's going to be z normal and then quite simply we follow this with the percentage sign f which is indicating that we're going to follow this with a float value and then outside of the brackets here a comma and then that float value that we wanted to print so it's basically this is allowing us to convert a float value to a string value and then print all of that message as one string so it's going to say z normal is the hit direction which is being recorded here so again i'll drop some of this dyno line so it's a bit easier to see that's the whole thing that you need to copy him other people you might see use something like the ue underscore log is another way that we can do messages the problem with this this goes into the output log so you need to then open up other windows and check through the output log i quite like when possible with the on-screen message one it will remind us to come back and remove this at some point because we don't want this to always be printing to the screen second is very easy to see whilst we're playing what is being recorded so again we'll hit compile that is now definitely ready to go and then we'll jump back over to the engine whilst we're in the class still i'm just going to remove the on component hit function we shouldn't need that we don't want to have any clashing with which one's being called and what i'm going to do i think this one might be working we'll come in press play jump up and we're still not getting that message or the jumps refresh so again we'll do a quick recompile make sure that that's working we're still not getting that called so the binding isn't working for some reason so at this stage we've tried pretty much everything that would be reasonable with the debugging trying to add in different print strings we can see that the function is being called in the blueprint but not in the c plus plus version we're not getting any errors related to an invalid binding or no references so there's nothing wrong on that side of the code so we've now hit what i think will be one of those kind of unreal quirks which you're just going to have to get used to this happens if the problem is what i think it's going to be like i said this isn't scripted or planned i'm kind of working with this as we go through but i think this is going to be one of those problems related to working with c plus inside of unreal and it's one of those things that has been prevalent in the engine in the earlier and later four point versions so again it's just something which is unfortunately rolled over to unreal engine 5 as well if it is the problem that i think it is so what i think we're looking at is an issue with kind of references rolling over from our c plus implementations into the updates in the editor they're just not being passed across this can happen quite often if you're working back and forward to going from your code to the editor and it's a fairly standard process you're very very rarely going to know exactly 100 what you're going to be putting in your functionality your classes so you will have some trial and error compilation coming back and forward and sometimes we can lose some of the links that we want so generally there are two ways that we can look at fixing this now the first one both of them are going to be pretty destructive the first one's a little bit faster so i'll go through this one to begin with either way we're going to have to reset and set up all of our player class again but this one hopefully will be like i said just a little bit less destructive so the problem is really that the function that we've bound hasn't been updated when we've been compiling or hot reloading so we're not going to force it to recognize this the way we're going to do this you can see at the moment we have the player class set to rollable player we're going to go up here to the class settings we're going to drop this down on the right hand side where it says the parent class here and we'll set this to be pretty much anything i think the best choice will be actor because there won't be any components conflicting when we select this we'll get a warning message just to say that some data will be lost as i said we're going to have to reset things so that's fine we'll tell it to re-parent anyway and then you can see here all of our components have gone we've got the default scene route which is pretty much what i expected the next step is we're going to come back and we'll drop this down again this time we'll move all the way down and we'll find our rollable player again and all we want to do is just re-parent this back to the rollable player so a bit of a strange process but basically what happens at this stage is the constructor that we have in the c-plus plus file if we had this set up to debug this would have just paused the code compilation and it would have showed us that actually just ran back through the construction script which means all of the bindings all of the components have just been remade and we now have that fully refreshed so a lot of the time you'll find that this is going to fix that problem that we've just had this does mean of course that we know if we go to the viewport we won't have any of the static mesh or anything set up so we're going to need to drop this back down we're going to go to the settings button here and once again tick on the show engine content we're going to look for the sphere component again and remember we're looking for the one which is 100 by 100 so i think it's the second option if we zoom back out just a little bit we can see the camera's too close so we're going to grab the spring arm making sure we do all of those same steps as before so we'll grab the spring arm set this to a length of 1000 and turning off the pitch you and roll and then we'll press e to enter rotate and we'll rotate this 30 or 40 degrees then quite important as well is the collision settings have probably changed so we're going to go back to the mesh before we forget the first thing of course we definitely want the generate hit events to be ticked again um and you can see that this is now changed one thing here is because we now have this uh predefined in the code remember we've updated this and it's now automatically set to simulate physics which is going to be very useful and it's changed some of the collision presets remember this used to be a physics actor which is pretty much exactly the same this won't actually make a difference because remember regardless of what the object type was set to it was already set to block all of these different types so that shouldn't have made a difference but the important thing is that we do have this set to block everything and the generate hit events is set to true in fact we can even just to double check this we'll just set this back to be a physics actor that way we'll know that for people following along if you've had to follow these steps to kind of try and fix everything we'll just be certain that that wasn't just a simple thing we could have swapped this to block all to solve the problem so now if we come back in with this so there's a physics actor we've got our simulate generate hits ticked all of the camera and everything's set up we can by the way just play from here if you wanted to test it quickly but we will need to come back into the editor to make sure that we possess this again so because we've lost all of those references and all of the default settings we had on this one we'll need to scroll back down go to the auto possess player turn this back to player 0 which is the first player in the game and hopefully now if we move this up a bit we'll press play and we can see there we go so we're getting our print string so it's telling us where we're hitting something and i can jump multiple times as soon as we hit the floor that's now being reset so for me that solved the issue hopefully for most of you following along that solved the issue as well if it hasn't what i'd recommend at this stage is you're going to have to recompile everything in your ide make sure that you restart the project to see if that will fix things if that final step hasn't fixed it the last result to this type of thing is you're going to have to delete your player class and then just follow the steps that we took earlier in the video so i'm not going to repeat it now because it will just be almost pointless repetition but basically quick summary you're going to delete the player blueprint entirely it will tell you there's some references and you have to say yes to get rid of those you're then going to want to come into your code file right click on this choose to create another blueprint based on this class and just save that one in the same place that the previous one was so inside of the blueprints and the game folder called bp underscore player and it does mean unfortunately you're going to need to go through this process one last time of setting up your mesh remembering to keep these really important variables so just rewind the video a little bit to that last step to see how we set these back up and the spring arm as well now when you've done that that should be there and like i said both very destructive processes we have to remove or change the class usually you're going to fall back on completely deleting the class as a final result but when you have done that you should find that will solve the problem for everyone who hasn't had the problem solved by this process of just changing the parent class so like i said slightly annoying probably useful that we found this in the video though it's nice that i've been able to demonstrate a problem which is unfortunately something you'll see quite often when working with c plus plus obviously there's a lot of very clever stuff going on with the hot reloads having everything be updated from the ide straight to the editor having all of the things exposed his view functions and new properties is all very very nice but there will be some kind of slip ups like this in the engine this is just another one of those examples as well which i would say kind of highlight why you don't want to make a hundred percent of your classes c plus plus just for the sake of it i've seen people who will create a c plus class just so they can derive a blueprint from it and then never implement a line of c plus plus in that class that is just an extra step it doesn't provide any extra performance it takes extra time for the compilation you open up to issues like this and this is one of those things where i wouldn't want to say that anything is better than the other but there are definitely situations where you have to balance what the best approach for your project and the the goal of your class or object that you're implementing is going to be and whether it definitely needs to have that c plus hierarchy so just a small takeaway there but you can see without changing a line of code i haven't needed to go back and change any of the bindings or anything this has all been done on screen that is the exact process i've taken to fix this class we now have this working so like i've said the the main goal of this is i'm going to come to the window option here i'll go to the place actors option and originally quite a while ago now what i wanted to show is if we drag in some shapes i'll get a cube and put this just above where the player can go make it a little bit longer so it's easier to hit and then why not get a sphere as well and let's throw in a cone just for fun what all of these are going to show i'll do a quick play through and if you're following along as well what we should find is when we press play and roll around if we hit the the cube so if we jump up to the cube from underneath we'll get that minus one which is showing that we're hitting it from it's we're being hit from above and if we roll around on the sphere and the cone we'll get some different values there so it can be a little bit hard to see because obviously it's printing so many things so often when you're hitting things you're essentially being returned for as long as you're hitting a certain thing so it's actually constantly updating what you're touching but you can see that the sphere was very easy to see the indication that we're being hit from different angles on our sphere and the same with the cone it was returning something like 0.4 whereas the sphere was returning 0.5 ish so almost directly midway and then the cube when we jumped into the cube from below we were returning -1 just jumping back over to our code file whilst we're going through the rest of the project we're of course not going to want to see the debug messages on screen constantly one way if you were interested if you did want to get less things scrolling down and wanted to play about with that viewport a little bit more the reason is pushing things off is because we've told all of the messages to last for 15 seconds if we turn this down to something really low we should only be getting a few messages on screen at a time and it's going to be a little bit easier to see so we can see that i've just dragged the sphere back in and it's still showing a lot of things on screen we could make that even lower but we can see at least that it's a little bit more readable we can get a better idea of what's happening just a quick example in case you did want to play about it with something like that a little bit longer again i'm going to get rid of the sphere and jump back over to the code so with this if we're finished with a comment here uh what some people will do you've got a shortcut here which is ctrl k followed quickly by c so keeping your finger on control pressing k and then c very quickly after each other will provide a comment around everything you have selected some people will comment out code like this uh when you're finished with debugging just to kind of keep it there now i know for certain that we're not going to need to test the hit direction again we have that working there's no question that that is now working and we don't need to kind of test or look at what is being returned at any point so the better option here to keep the code nice and tidy as we go through any debug logs or printing that we were doing we would just remove as soon as we don't need it the same for old code just again a good programming practice to get used to you might think that there's a little bit of code that kind of worked but wasn't doing what you're expecting so you'll comment out you'll leave a comment to a certain extent that you might come back and try it another time and then more than likely we'll just forget to do that so it's always best if you're not sure if you're going to keep something in just remove the old code at worst you might have to re-implement a little bit of code which was broken to begin with and you may come up with a better solution the next time around it means that your code base is going to be much cleaner a lot easier to maintain and you won't have just tons of comments taking up a big bulk of your code area so with those changes finalized we can now go back over to our editor and we can move on to the next topic which i think will go straight into the interactable items that we'll be placing around the level back in the editor we're going to go straight into our item class creating that one so we're going to want the content browser back if you haven't hidden this already it looks as though we still have our extra settings showing so we can click on this and we'll hide the engine content again we might need to scan a little bit later but that will be fine so if we navigate to our classes and select to create a new class in here what we're going to do is we'll be choosing the actor class for this one so again if you're not familiar something like the class hierarchy this will be another learning opportunity for you is to look into the class hierarchy system inside of unreal a very brief overview again if we drop the all classes down i've kind of touched on that the pawn class that we're using is the kind of most base class or the lowest level class that we can use that can be controlled by a player that derives from an actor and the actor class is the lowest level class that we can place in the world so something like a pickup is going to be something we need to place in the world so we'll need an actor very small kind of side tangent here i will class this as a sponsored by section as i don't take many sponsorships for the channel this video i'm going to decide is sponsored by my own course which as i've mentioned you can find in the description below it goes a lot more in depth into absolutely every step we take just like y and when we would use different classes from the unreal engine hierarchy building on this class inheritance system so if you wanted to know a lot more about that type of thing as well as things like setting up git repositories the best types of classes to use for certain instances creating completely flexible and custom systems for things like level spawning where we create our levels through the use of spline systems and tons more things like that then do consider taking that course as i've said it is blueprints and i appreciate that most of you here are going to be interested in the c plus plus side of things but it will go into a lot of transferable logic algorithms and things which will be very easy to move over to c plus plus and it's going to get you much more familiar with the unreal engine if you're new to that we'll consider this as i said a sponsored section for the video it was that or something like raid shadow legends and we know that nobody wants another one of those so what we're going to do now we're going to select our actor class then to create our interactive pickup class that we'll be working with i'm going to class this as an item class we could have named this something like pickups or collectibles the important thing is we settle on the name early on because we can extend this to potentially other classes spend some time in research that as well then with the name selected we'll follow the same folder structure as well so this one isn't going to go into the games folder this will go into its own new folder named items and again this will just separate things out quite nicely if we did want to create other item types and have that inheritance system then again we now have a folder for all of our different types of items it will make things super easy to find and work with and when we have that done we can hit the create class option again this may take a while to compile and we are going to get that include issue as well where the directory is having the folder included where it shouldn't but we now know how to fix that one okay so that compiled quite quickly for me again as i said we're going to get this error we'd get the same message so we can say no to this we don't need to look into this one we will need to jump over to rider or your ide of choice if you don't already have that open whilst we don't have that new class again like with previously it won't be appearing in our folder structure you can always just jump into one of the classes or at the moment the only class that we have and navigate to it that way so what i'm going to need to do because i'm in the presentation mode i'm going to go to the view option show the explorer again it really seems to have this drop down for me but if you haven't already your view main will look like this you're going to want to go to the games folder which is our current game folder the project then the source which is where we're keeping all of our custom code files and then in here the youtube underscore rollable we can see we now have the items folder so again it's all gone through we have this created successfully and we have our new classes so inside of the header we'll need this one open so i'll get that one ready inside of here we're gonna have all of our main information we've got our constructor like we've had in the other class our begin play and tick so whilst we're here we can just get rid of the tick because again i know we're not going to be doing any checks or functionality on the event tick which means we can then go straight to the code file as well and this is where we're going to have a problem so remember whenever you remove the definition you need to remove the the actual code in your code file as well for the event tick for instance there then for the include we're going to want to drop this down we'll take the same approach i'm just going to delete the folder name allow that a few seconds and we have that fixed i'm going to hide this again so i get a little bit more space on the screen alt o back over to the header and we'll start doing the bulk of our work in our item base header the first thing i'll be doing is in the public section creating our u-static mesh so again we're going to define our static mesh like with our player this won't exist we're going to need to create this a little bit later i've given this all of the same u properties so visible anywhere same reason again because it's a pointer to a component we only want this to be visible not editable we're going to make this blueprint read only so again we also can't change it in the blueprint but if we did want to find any information about our static mesh we can do that and it's put in a category named components then moving down to the protected section we're going to need a couple of functions we'll want the custom function for when we overlap something and we're going to need to get the signatures a little bit later so for now this is going to be our function that will be binding so again we've seen all of this but this is going to be a binding of a slightly different function so we can see it working a few different ways so the first important thing is we add our u function and remember because this is going to be a delegate or a bound function we don't need to provide any meta specifiers or anything we just need it to have that u function status this will be a function of type void so a untyped function named overlap begin now we will need to get the signature information as we've done previously it's going to be a little bit easier to do that when we've moved over to the code file remember this is a completely custom function so this doesn't exist in the engine we've just defined this new function named overlap begin then just below this i'm going to create another function named collected again of type avoid and just above this one will be slightly different i'm going to provide this one a u function and we're going to use something we haven't seen yet which is making this a blueprint native event so this is going to be one of the first times where we will be doing some of the logic in our c plus code for this one but we'll also be doing a big bulk of this in the blueprint because it's going to be a lot more visual and it's just one of those things where it makes more sense to do it there and i wanted a kind of excuse to show how we can share some of the code out and implement this type of function now with both of these we're going to need to create a implementation our collected function is going to be a little bit different the way that we implement this you can see it has a red error message already which is uh because of the blueprint native event type that we've given it so what we'll do for now is we will ignore this just so that we can kind of speed up the implementation of these a little bit later we're going to hop straight to the code file and the most important thing at the moment is to get our constructor set up as we want so the first thing will be to set the kind of attack to false as we're not using that tick function anymore then for our mesh we're just going to again this is very similar to what you've done in the player class we're going to say that our mesh is equal to the create default sub object passing in the u-static mesh component type and naming it mesh if you remember even in the player class this is one of the components that we didn't need to forward declare or include the library of pretty much every class has an understanding of the use static mesh as it's such a generic component and as we've done before we don't really need to because this will be the only component in this class at the moment but just to avoid ambiguity or confusion we're going to define here that the root component is the mesh that we've just created it would actually default to that anyway but again but in this case one line of code to save ambiguities seems like a pretty decent trade now the next thing is going to be our binding to our custom function so again we've seen most of this process before we're going to want to use that add a dynamic binding function which remember we do through the mesh and we want to find the function within that mesh context that we're going to be binding to so if we get this started this is going to be the mesh and then the operator and we're looking at in this case what type of function we want to bind to so that's why i've stopped here at the on component because we have a lot of different options remember previously we've used the on hit and this is again really going to kind of make us consider what type of collision event we want our player to have with the pickup now if we do another on hit what could potentially happen because this remember is our blocking event this could lead to things like the player before the pickup generally gets destroyed is going to be the end result of most items or pickups that we'll be implementing what could happen that kind of frame or two before that happens though is the player could hit the item and have like a small kind of nudge or push back effect and to some people that won't be noticeable but there will be players who find that quite annoying it's going to feel that a little bit jarring and a little bit kind of buggy almost i suppose when you want to just roll over something and pick it up but you get a slight nudge back from it so that means the on component hit is pretty much out kind of ruled out of the equation there so of course all of the other things like activated created deactivated all of these are irrelevant all of these are called when the component is first instantiated and we don't need to worry about that so that leaves the other two which are going to be the overlap types and we've got begin or end overlap and of course we want this to happen when the overlap first happens so we've found the function that we want to bind to just through thinking through the process and eliminating the ones which don't seem so relevant so we're going to use this one and of course we're going to do the add dynamic function call again and then we want those things that we're going to bind to these two and we actually have these already so we're going to say this again so it's going to be a function within this class and that function of course is going to be the overlap begin on the a rollable item base and obviously we're using the address accessor there now you'll notice one thing this throws an error and it also didn't suggest that one is the first function for me to use and the reason being is what we've kind of looked at in the past is that we need the parameters to match the parameters that this function will be expecting which is why we've approached the process this way so that we have this to drop into and find those parameters so like we've done before we're going to use the navigate to option here so we're going to go to the declaration of this function and we want to whilst we've got this selected just ctrl f again go to the other there's only two places this is used and remember we can ignore everything before this we've got the function name and then we have all of our parameters that we need for our custom function so that was the main goal here just so that we had this ready to use and we can see this one's quite long so i'm going to copy all of these again i'm just going to go back into the header file and like we've done previously we'll paste these in now as of last time we're just going to get rid of the comma if you're in ryder it's going to be the comma just before every block of red text otherwise it's just the first comma and then every other comma afterwards just before this boolean i'm just going to drop this down so that we can see this a little bit easier and then the final one here we have the sweep result and we now have a valid function with all of the parameters which means if we drop back over to the code file that has now synced and updated correctly so that is the mesh created set as the root component and then bound the function to the on component begin overlap so now whenever we overlap this our overlap begin function will be called so the next thing then is how we're going to use these we need to implement these of course so we're going to come back here again if you have the shortcuts then i'm going to show you the shortcut route first of all and then i'll go through the function declarations if you need to do it manually so for me i've got the alt and insert i'm going to go to definitions and tick both of these now i'm not actually sure if this is going to work but the collected function needs a very specific type of implementation this is something i haven't automated in the past or if i have i've not considered it whilst following the process so it's going to be interesting to see if ryder uses the correct implementation so we'll tick both of those see how this goes and press ok and it actually does so brilliant so the first thing we can see we'll look at the overlap again first so obviously speeding up this way means that we have all of the parameters passed through immediately which is super handy as i've mentioned if you don't have the shortcuts available depending on the ide that you're using then like we've done in the past remember you just copy everything including the void so we'll copy that over we paste that in prefix the class and the operator just in front of the function name and then close it off with the curly braces remember no semicolon needed here so that would be the first function and then the second one you could probably hand type this just as quickly because this is where the blueprint native event is slightly more unique so what we you can see here that ryder was clever enough to pick up that we need this underscore implementation the reason for this is because this is native to blueprints is the idea it means that the bulk of the logic is expected to be handled in the blueprint so we're going to have a blueprint function created almost by default when we compile this and to separate things like that means we can access this function in c plus plus but we're going to use the implementation function instead whenever you're working with these blueprint native events just remember that you don't create the collected function definition as we've done in the past instead we create the implementation version of the function i'm not 100 sure why this hasn't synced up that error message should now go away but we'll compile this and see what happens and it could just be one of those false positives we get back sometimes seems to be the case so maybe now that i've compiled that that will go away yeah so that was just a false positive we can ignore those and what we can do we'll now implement the last part of our code this is going to be very simple we will need to come back a little bit later when we have a game mode implemented but we can do the bulk of the logic here so if we start with the simple one which will be the item overlap begin if we consider what this is going to be doing as soon as the player rolls into this item we want something to be checked and that is really just going to be checking whether or not the thing that we're hitting is the player or the thing that's hitting us is the player because that's really the only time that we're going to want to be classed as collected if we touch the floor walls or something like that obviously you don't want your items to be collected so this is very simple we have again all of this information in the parameters here the only thing that we actually need is the other actor and what we want to do is use an if statement so we're doing a conditional check here and we'll be checking whether the thing that we've hit so the other actor is equal to a certain thing and the way that we do this is we actually use a cast so we'll cast two another actor type and in this case is going to be our a roller ball player now this will give us a warning because uh or an arrow because it doesn't know what the rollable player is it's a custom class that's not going to be included in the include what you use system of the class libraries so just want to come up here and we'll include the rollable player class here one thing to note you'll see that i'm going to include the yt underscore rollable folder so the project folder then for this we will actually need to direct it to the game folder and then inside of that the rollableplayer.h which means we now have context we kind of understand what this class is so the final thing is we actually need to encapsulate this so what we're saying is this is like our context check so we're going to encapsulate the argument here that we're checking against so what we're looking for is whether the other actor is casting to the type of a rollable player so what this is saying is we're passing in a generic actor type we're then going to compare so when we've got the other actor so when something is touching the pickup or the item we're going to take that actor and we're going to check it against another class type and we're going to say is that class type equal to the rollable player type so does it convert correctly to being a player so if it does then that means that we're going to get a valid return here so i'm going to say if this isn't equal to a null pointer basically saying after this cast check this kind of conversion if the value is still stored means that we have cast successfully and it is a player so it isn't a null pointer so it isn't left empty is essentially what we're saying there we've now confirmed that we have hit the player type so we want to call our collected function which is going to be remember the blueprint implementation version of it so note that we're not calling collected underscore implementation this will call the blueprint function which when that blueprint version the native event is fired that is what is responsible for calling this version here so this will actually be getting called we just don't need to do it implicitly inside of our code now pretty much everything which is going to happen in the implemented function we'll be doing the important stuff in c plus plus still all of the communication with our game mode tracking how many pickups and things have been uh collected or how many items have been collected all of that will be happening in our c plus plus code it's only the visual side of things we'll be doing in blueprint so i'm going to leave myself a comment here kind of to that extent doesn't always need to be the most clear comment but that will just remind us that we're going to come back and in fact something we can do is we can throw a to-do at the beginning of this and this will actually change it to a kind of special comment and we can search very easily for to-do's so if there's something that we know that we absolutely cannot forget that we need to come back and do we can leave this as a to-do it kind of highlights it and we can find this in our inspector much more easily so for now though that is the bulk of our class ready to go so again we can compile this and we can go over and create our blueprint version and start adding these to the world back in the editor then because we've recompiled this you should now have the items folder and the rollable item base if you don't have this for a certain reason then just remember to save everything you've done in the editor restart the edit turn again just to process you'll get kind of familiar with to get this to be shown again what we want to do this time i'm going to go back into the blueprints folder quickly create a new items folder in there so again all of my blueprint folders are going to match the code structure and then returning to the classes structure in the items folder right click on the rollerball item base choose to create a blueprint class from this as we've done in the past and put that into the items folder this one i'm just going to name bp underscore item base i think for this project we probably will only have one but again you could easily derive other classes from this if you wanted to you could have item red green blue and so on and they could all do different things or whatever you wanted to do inside of the class it looks as though everything's updated correctly we have a mesh named mesh and this will be in our component section we can see as well we didn't need to turn on any any physics or anything that's not going to be physics actor this is just going to be overlap it does mean that the first thing we'll need to change is we'll come down to the collision presets we'll change the block or dynamic to overlapple and of course we're going to want to give this a static mesh as well so what we'll do is we'll drop this down we'll go back into our show engine content option again as we're getting quite familiar with now and this time i think i'll make this a cube so we'll just look for cubes and again we want these smaller cubes so keep in mind the approximate size down here uh we want the one which is about the same size as the player and we're actually going to probably lower that again a bit anyway so we'll see if there's a smaller one so this 50 by 50 cube might be quite good i guess it looks fairly interesting as well if you like the emissive colors and that will do fine for now so we now have something which will have a collision which is going to be set to overlap when we collide with the collision information on this cube so that is pretty much ready to go and the final thing is we're going to want to expose that function that we've created in our code file so that we can do that blueprint bulk of work just here now the way that we do that is we're going to go to the function override option just here in the left hand side we're going to drop this down and we can see that we should have you can see all of the functions that come by default in the actor class scroll down the side here with the word actor so these are all built-in functions that any actor has that kind of understanding of or built into that code base we also have our new one the rollable item base function called collected so that's the one that we've made we want to click on this and that will give us a new event here and this is where we're going to do that kind of visual stuff so i think first of all let's double check that we can drag this into the world that looks about the right size to be just a little bit smaller than the player so we're going to have the player rolling around and picking up some of these we'll have one for now that should be perfectly fine and what i think would make this look quite interesting is rather than adding all of our components through code we can very easily add again the visual aspects just here so we're going to add a new component i'm going to choose the rotating movement component and what we've just done in a few seconds there is the equivalent of what we've been doing in code which takes a little bit longer and again this is a nice way to get those visual aspects in just to test if you do want something to rotate we've basically created as we've done with the mesh we've created a rotating movement component which at runtime will make this rotate around itself i'm going to change the speed a little bit i think 90 on the rotation rate on the z and the x might look quite interesting and if we press simulate we can actually see what that's going to look like so we've got full control over how this rotates we'll need to stop simulation if we turn that off you'll see this just rotates around the zed which i've zed is up so it's just going to go rotating around itself like so and of course changing the speed is just going to change how fast this rotates so in fact i think for this maybe just on one axis is going to look pretty good we'll leave that just rotating on the zed and again it's just so that when we have a bunch of these in the level we can start alt clicking and dragging so if you hold alt and then click and drag and then you'll need to release alt and click and drag again to duplicate these when we press play now it just makes things look a little bit more dynamic and a little bit more interesting the next thing is to check that we have this working so i'm going to drag these down to make sure the player can touch them i'm going to go back into the class and in here the easiest thing to check this is working is we'll call the destroy function from the collected event so that means now that when we touch this with the player these should all start disappearing it seems as though we're having that binding issue happening again as this function isn't being called so before completely destroying classes again although we shouldn't have to this time because we had that bound before we've created anything so in fact let's do a little bit of debugging let's check the most obvious thing first of all which will be whether or not we are having anything overlap with us so we'll just plug this in here instead so as soon as the overlap is called this should now destroy us okay so the overlap event again is working so we've so we know that the cube has collisions enabled which means we'll want to make sure that we've had this recompile we'll do another hot reload down here just to make sure everything's synced up as much as possible and we'll give this another go and there we go so this time actually that was quite handy it was just a simple recompile that we needed and we can see that we now have the actor being destroyed when it gets collected so next i want to add that visual flash so before we actually destroy anything i think what i'll do is increase the speed at which we're rotating just for a short period of time and then we'll make it disappear so it'll kind of show that something's happened in between touching it and being destroyed so this is again why we're doing this in blueprint we've got access to all of the components we're creating here we're going to control drag in the rotating and movement components so hold ctrl drag this in and you'll be getting a reference to this component or the object data of the component and what we want to do from this pin is get the rotating rate so remember that anything that we can see on this right hand side basically when we have a component selected so all of these variables and exposed properties can be retrieved from the component so we're going to get the rotation rate we've got two options here we've got get rotation and set rotation rates which is this one just here and we can split this by right clicking on this pin this is just three float values we want those separately so we're going to split the structure pin and remember we're only rotating around the z so we're going to grab the z and i think what i'll do is i'll multiply this by something like 10. so i'll make this 10 times faster than it currently is so it's going to be a very obvious change in speed and the next thing i'm going to control in w to copy and paste this in one go again this time i'm going to set the rotation rate so find the rotation rate again choose the set option and plug this in just here and in between the destroy actor i'm going to right click just here so we'll split the structure pin again and what i want to do is just plug in the rotation rate it's nice and simple now at the moment we wouldn't see this because as soon as this gets set we're destroying the actor so let's throw in from here a delay function so this delay node is going to pause the order of operations for the given time here i'm going to set this to let's go with half a second and then after half a second so this will rotate faster for half a second and then we'll delete or destroy the actor so let's give this one a go okay so that is very very fast i think what might be happening here yes that's what we expected on that one i think what's happening is remember that for the duration that the collision is being checked against this is going to be getting called multiple times so we can do a quick print string here we can see how often this is happening so i think we're multiplying this a few times by 10 with some of those cubes which were moving really fast that was once that was once it's not happening now they're all going the correct speed there we go we see that one got called four times so that got multiplied by ten four times so quite simply in between this then another thing we can do is use a do once function so this as the name of the node suggests means that this functionality will only ever be done once unless something calls this reset execution pin just here so now regardless of how many times we overlap with this we're going to enter this once do that functionality just once and because we're not resetting it we'll never do this again now the really important thing here something that's going to be very easy to forget is that we still need to account for our c plus counterpart so our implementation now at the moment that's not going to be getting called the way that we call our c plus version is we need to right click on this we want to go to the add call to parent function so again this is very important please include this because if you don't hook this up just here so i'm just going to hook it up between the do once so again this only have gets called once as well we're going to call that function in our code so this is what's going to be calling the implementation so do a quick cutaway just to remind you it's calling this function when we call the parent version of the function so this is really really important so make sure we include that because when we get our game mode created in a moment it's going to be this version which causes the implementation to do the communication adding the items collected and toggling things in the game mode so all of this is purely visual great for blueprints nice and quick to implement custom component which was added in seconds and now when we play this we have that nice functionality working in the blueprint side and then that's going to allow us to also utilize the c plus plus side that we'll be getting to a little bit later for now then unless we're going to do any kind of big visual overhauls that is the item base class done so we can close this the only reason i think we're going to need to go back in is if we decide that this cube isn't really what we're looking for but again we're not going for a visually impressive game we're going for a working game at the moment so the next thing we want to do is to create our game mode so that's the term that i've mentioned a few times to this point and you may be wondering what a game mode is if we go into the project settings very quickly one of the things that you have to get used to when working with unreal is it has a kind of structure that is expected to be followed part of that structure is we've got things like the map system so we're currently in a map named main every map has a certain thing that needs to be included which is a game mode and by default if you don't specify a game mode per map it will use the project default game mode which at the moment is our game mode base and each game mode then has a bulk of information that it also expects to be filled if you don't fill it then again it will use the default versions which in this case would be things like the pawn to possess would be the default pawn default huds player controllers and so on we also have things like game instances but this is going to be a little bit too specific and more technical than intended for this short course but the reason that we'll be using a game mode and specifically our own custom game mode is if we come back in you might remember a little bit earlier i mentioned that this isn't an ideal way to place a pawn or the thing that you're controlling into the world we've had to come in we've had to manually override remember that it's this player that we want to possess as player zero now if we remove this and just press play you'll notice we have a player start actor down here what this will do is the game mode will look for a player start in the level and if a class hasn't been defined we're going to get something called the default player so now when we press play we're now in a first person view we've got the standard wasd movement control is down space is up as well as q and e for dining up and you're looking around with the mouse if we press f8 this will eject us from the the viewport and we can see that we have up here the default pawn now remember in the default game mode the thing that is expecting to spawn in is the default pawn and that is exactly what we've happened here we've also got the default player controller should be somewhere or just the player controller and all of this is being controlled and bonded in based on the game mode settings so this is why we're going to want our own custom version of this so we have full control over what's being spawned in what's being possessed at what the human player is going to be possessing essentially so again we've definitely finished with the engine content now so we can close this hopefully for the last time to create our game mode we're going to come back into the game folder so again the kind of more generic things that all games need i'm going to put in here i'm going to right click and create another new class we're going to go down here because they're quite common classes you'll find it in the comments section and we'll look for the game mode base we'll press next and similar thing is always we're going to choose our naming convention so i'll call this one rollerball game mode base we've already selected this to be in the game folder and another thing just keep in mind the reason we're calling this one bass is you may have different game modes for different maps so that would be things like our level map that we have here the main map would be the game play game mode we might want to create a variation being a menu game mode which wouldn't need a certain player class because of course you don't have the player running around the menu and that would control things like the different inputs so it would block the game input and change it to the ui input so you've only got the mouse showing the cursor and things like that so again all a little bit more complex or in-depth than we're going to be going here we won't have menu systems and things but just in case you did want to extend this i'm going to call this one game mode base so again any derived classes will be easy to distinguish what the base or parent version was and where they come from so with that done and set we're going to create the class here and again we're expecting a compilation error at the end of this okay there we go nice and quick again but we do have the message so we'll say no we're going to go to our old routine we're going to jump over to the ide for me again i'm going to need to change the view to show me the explorer and then hopefully you've got this folder structure open we're going to go to the game folder the game mode base code file we can just go straight here this time and remember nice and simple just remove the folder that we don't need then as we have that accessible i'm going to go into the header file and as always this is going to be where we do a bulk of our defining or declaring the things that we want to exist within our class and then we'll hop over to the code file a little bit later to implement them the bulk of the gamemode class then is going to be very very simple to actually implement and there's just a few things we really need to consider so the main thing that this will be controlling besides those default project settings we've discussed which won't be getting set in code anyway again if you wanted to see why we're going to avoid setting things like the player class through code that is all covered in the course that i went through with epic showing how to utilize both and it's kind of a security measure where hard coding or forcing things like that to be set in code can actually be a little bit detrimental so again if that is interesting to you then do check out that content there's already a bulk of information there which is why i didn't really want to repeat things too much here but the things that we will be handling inside of our game mode then we've got a few things to consider and once we've kind of pinpointed all of these topics then we'll know what we want to include in our header based on the type of functionality that we'll be looking to implement so the first thing is that we'll be creating our widget system so our small kind of heads-up display to show how many items are in the level and how many that we have collected will be in a widget class which will be getting spawned through the game mode and then everything in the game will communicate with the game mode to update things like when the items have been collected so that they can then be passed to the widget so that kind of tells us already that we have two variables which will be the number of items in the level and the number of items collected so we can do this straight away i'm going to drop down below and i'll put this into a protected section and these two variables will be of type int 32 so it's just a single point number no decimal points which is where the floats would be used and i've called one items collected and the other items in level and set both of them to zero just so they have a default value the reason we're using int 32 rather than just a standard int is just part of the unreal kind of programming practices we could use an int 16 if we know we're using something really small or a standard int should work here as well but you'll find that when you're working with other people's code you usually default to 32 and it's one of those things you just get used to the programming standards of the platformer engine that you're developing with so the next two things we'd ideally implement would be the user widget itself so the class to display on screen now we don't have that created yet so this is going to be one of the times where there'll be a little bit of back and forth between the classes we'll need to implement some functionality in the widgets before we can put them in the game mode but we'll need the game mode doing some stuff before we really need to spawn the widget so we're going to get the basics down and then we'll come back and revisit this a little bit later so again i'll leave myself a quick note here to say that we're going to come back and implement the widget variables then we'll need two other functions in the protected section i'm going to create one which will be a virtual void begin play override and the next will be the void update item text now the first one the begin play is a overridden function which means we're basically implementing a function that exists in the code elsewhere so inside of the a gamemode base that we can see here at the top the public a game mode base is our parent class that means that this and potentially the parent classes of that class have a function named beginplay that they implement by making this a virtual void override that means that we can utilize whatever functionality is happening in the parent version of that function and we can also override it with some custom logic in our class if you ever see that that's basically what it means again another small learning opportunity is to take some time to really get an understanding of what virtual functions are and when you would use overwrites then the second function is the update item text which is a custom function we're creating and this is going to happen every time an item has been collected we're going to want to update the widget that we'll be coming back and implementing a little bit later finally we'll create a public section just below this and a single function again of type void named this time item collected now this is going to be the function which the items will need to contact essentially the gamemode class that we use and it's going to just pass a message and say i've been collected and then that collected function is where we're going to store or update the information to the widget using the update item text now hopefully you've gone away and had a look into the private protected and public sections as that was one of the learning opportunities that i posed a little bit earlier if you haven't then again now is still a good time to do that but what i would say is just so you have an understanding very briefly the reason we have a protected section here this means that nothing outside of this class will be able to access any of these variables or functions the difference between private and protected is anything that this class will be used as a parent of so any classes that derive from this custom rollable game mode will be able to access for instance the update item text and they will also be able to access variables which if we made these private even child classes wouldn't be able to access them and in a similar way that would mean that the virtual void begin play that we are overriding from our current parent which is the game mode base also has this placed in the protected section and then the public means that absolutely everything can access this so this is slightly less safe it means that anything could potentially override variables that you put here from outside of this class other classes can call functions which sometimes will be required like with the items needing to let the game mode and know that it's been collected sometimes we'll need things to be put in a public function but that's why we're going to limit this to one function and this isn't going to edit anything this is essentially just going to notify us and then we'll do the actual functionality in our protected function which means that nothing can override this by accident or something outside of our class so with all of that in mind the final thing is we're going to alt and insert if you're using rider to create our definitions we'll select all of these and we'll say okay and we'll allow those to be created so again very simple functions just the class name and the functions no special implementations or anything here in the game mode code file at the moment there's not a whole lot that we can do with the information we have readily available like i mentioned we need a lot of that information from the widget we can look or consider how we're going to be tracking the items so the items in level and also the items collected so we'll get that out of the way now and that means that when we return with the widget stuff we can jump straight in to testing things and hopefully if we get this stage right it should all just work immediately later so the first thing is on our begin play so as soon as the game starts we're going to want to drop into here and find out how many items are in the level now this can look quite daunting there are going to be a few different steps that we're going to need here to get this working but i'll put this on screen for you and we're going to get rid of these issues so you can read it as i go through so the first thing we can see we're missing some includes the main one for me i'm going to press alt and enter so when i highlight this in rider you can press alt and enter to create or include the path that is missing and you can see that that has included the kismet gameplay statics which is how we access this just here if you're wondering what i mean with the include what you use basically unreal has now got a code system where all of the includes have been stripped out to almost the bare minimum that every base class or the most generic classes will need to to kind of run and have the information from the libraries that they need to compile this cuts down on things like the amount of includes that used to be included in a class cuts down on the size of the different files and the class sizes and things like that increases the compilation time but it does mean that we need to make sure that we're always managing the includes that we use to keep things to a minimum but obviously have the information that we need at hand so in this case we need the kismet gameplaystatics.h for the u gameplay statics function call we'll be making and because we're going to be referencing our a rollable item base which is a custom class we've created we need to include the project name forward slash items forward slash rollable item base as we've done a little bit earlier so if we go through what we have on screen then to get all of the items that we have in the world it's two very simple steps the first thing is we want to create an array of items which will be collected and kind of put into a list of information we do that using a t array which is a typed array of type a actor so we're just saying that we're going to have an array of actors returned and we're using and then through the u gameplay statics we're going to use the get all actors of class function call and i'm actually going to remove this because what i was hoping is that ryder would show us next to it what the parameters relate to so i'm just going to type this out so that we get the context as we go through so the first thing if i start with the get world that was ready there that will show up pop up this which is what i wanted the parameters that we need to pass into the function so the first one is of type u object and it's classed as the world context the very highest level of class in the hierarchy that i keep mentioning even above actor is the object type objects are basically a collection of data they don't have in themselves any kind of reference to what a transform is or any way to be placed in the world which is where the actor comes in so the actor is the lowest level of classes i've mentioned which will have a transform in the world and things like the levels or the map are in themselves a type of object so what we're saying is that the world context object where we want to look for these things is the current world which is we're just using the built-in function get world which will basically return the map or world object that we are in then the next parameter it needs a actor class to look for which is why we've created a generic actor array but we will need to type cast this to the class that we're looking for so again remember that otherwise everything in the world is essentially at some base level an actor which means that this would return absolutely everything all of the static meshes the sky sphere the lights they're all at their base and actor so what we're going to do is we're going to say that we want to find all of the actors which are specifically our rollable item so we'll do that by saying the a rollable item base and then using the access operator we're going to use the function call for the static class conversion here so this is basically just a bit of syntax here that we'll need to specify that the classes that we're looking for is going to return the u class version of the a rollable item base and then the final thing is that we'll be adding in the t array and this one is specified as the out actors so basically all of the things of this type that it finds in our current world will be placed and stored in a list of actors which is really we can just look at it as a list of information and that of course is why we've created this t array over here which you can see matches the type here exactly of items so we're just going to pass in items so what we're saying is that we want this array to be filled with all of the information for each of these different rollable items that are found in the world we want one of them per item to be added to our array then the final thing is we're going to drop down one more line and we can say that the items in level so our integer value that we stored earlier this will be equal to the number of items in our array so the way that we do this it can vary between different languages but in our version of c plus plus is basically the items array so items and then dot and we're looking for the num function so the number of items and that is just a function call and we'll close that off with a semicolon so this is basically at the rudimentary kind of level going to return an integer value or a value which will be turned into an integer which will be stored in our items in level so now we know that the length of our array say that we've placed four different items in the level the number of items in that array will be four and that is going to be used as the items in level value that we'll be tracking so that's really all we can do in the begin play without the the widget to work with the update text function again is pretty much entirely based around calling functions on the widget and the items collected we could probably do half of this now which is going to be updating the number of items we have collected so remember we've created this we've set both of these to zero so at the moment we've collected zero items when we uh when we start playing so whenever this function is called whenever an item that we hit calls this function we're going to say that the items collected is equal to the items collected current value plus one so if items collected is zero we're going to say that the updated version of this is going to be equal to zero plus one which is one which turns this final value back into one i'm showing you this way just because i want this to make sense it's going to be very very useful to understand these uh kind of different shorthand operators so the way that we can simplify this is like we've done previously we're going to flip this around so rather than equal plus we're going to say is plus equal which means that we will have the items collected is going to be equal to itself plus one so basically again if it was zero then equal to itself plus one would be one if it was two then equal to itself plus one would be three and another even easier way for this is we're going to remove that entirely and we're going to use the increment operator so items collected plus plus is exactly the same as plus equals so it's just taking its current value and this is adding one to it we've got similar things like minus minus if you wanted to take one away these are the increment and decrement operators so very useful very handy and very shorthand and i just wanted to kind of visualize what they're doing these are basically calling functions below the um the codebase and it's taking into account what this is and adding a value to itself but it's nice and short for us to use with the very basics then implemented in our game mode we're going to go ahead and we'll compile this now we can start using this at the very least in the blueprint form when we create the child class of this and i'll show you how we can start implementing this into the project so that we have our default classes and everything being controlled as we want so go ahead and hit compile and head back on over to the editor with that compiled back in the editor i've just needed to restart the engine again because of that compilation issue that we ran into a bit earlier with the game mode we can now see that with that reloaded the game mode is showing mine wasn't originally which is why i restarted it you might need to do the same what i wanted to show very quickly and why we're going to be creating another blueprint version of this in fact we'll do that straight away so we've got the folder structure ready we'll right click go to the create blueprint class based on and we're going to go to our blueprints and game folder and we'll create a new blueprint named bp underscore game mode base select the create blueprint class and we'll place that class in the folder and we'll be working with this in just a moment so we can leave this open what i wanted to demonstrate though is if we go to our project settings the maps and modes we've already set the default startup map so this is one of the things we can control here the next thing as i've mentioned is the game mode and what we can do now we have two different options where we have loads of options but we have two options that we've created we've got the rollable game mode base and we've got the bp underscore game mode base now the problem with working with the purely c plus plus approach would be that we'd use our rollable gamemode base and you can see we still don't have any access to override the default classes which means what we would need to do is we're going to have to code manually in our constructor of our game mode all of the classes that we want to use usually this is done with hard references which is a really bad way of processing things generally at least because if anything ever changes and when i say hard reference i mean we're going to have to specify that the default player is going to be in a certain location so we'd say things like default player or default pawn equals the blueprints folder forward slash games forward slash the name of that class now the problem hopefully is quite clear to a lot of you is that if we even do anything as simple as changing the name of that player class and recompile then we've lost that reference if we change it from player to player base then obviously that doesn't match the text that we've typed into code likewise if we move it to a different folder if we drop it into a players folder because we have loads of different players in the end of our game then again we've lost that reference and we need to fix our code so what we want to do is we want to let the engine kind of handle as much of this as possible to do that we're going to instead of using the code version of our game mode we're going to use the blueprint version and we can see immediately this opens everything up for us to edit which now means that we can drop these down and the first thing is going to be the default pawn class we can change this to our bp underscore player and this is really the only thing we're going to be changing in this project but again if you had a much more complex game especially if like multiplayer games will be making use a lot more player controllers game states and player states then you could have your own custom classes for these as well but what this means is now when we come in remember the way that i said this works is we now have our default game mode to be this one here we have our default pawn set to be the one that we've created in our project and when we press play the project is going to look for the game mode it's going to find out what information we have stored here it's going to choose the default player class and it's going to place that player class wherever it can find a player start in the world so if we press play that one i just work kind of using the bethesda slogan there but this will actually just work so when we press play we start exactly where we expect we have full control and we can move around with our player class so nice and simple and this is what i was kind of going back on earlier this is why we don't want to manually drag things in override which one we're going to use as our default pawn because that can get a little bit confusing we can have conflicts you can set things up to you can forget to very easily forget to set them to be possessed or you could set them to be possessed by the wrong controller that might not exist and so on whereas with this wherever we have this we can move it and we can see that we're now going to spawn in a different place based on where that is so that is going to be why we want to make use of this game mode this is again one of those things just how the unreal projects are kind of intended to be used so you have to get used partly with coding and good practices and stuff but also kind of working around or with the unreal engine to kind of accommodate what i'd expect in part of the setup of the classes and and the projects themselves another thing to note in the game mode anything that we've changed in the project settings so for instance the default player class that we have here has already been updated we didn't need to change that here if we change this back to none then this also reflects as soon as we hit compile this will reflect over to the project settings so whatever you do in one remember that it will reflect to the other which is kind of handy but obviously it can be very easy to forget that you've changed it in one place and you might question why it's changed in your blueprint class for instance so the final class that we're going to need for our project to kind of all start coming together is going to be our widget class so again we can leave the game mode for now i'm going to go back into our code and like we've done previously we will base all of this where possible from a c class i'm going to place this one inside of the game folder as well so we'll go back here and this is another one of those just a heads up that this will cause issues along the line because we have this created as a c parent which is another reason i wanted to include this so you know the work around if you ever experienced it yourself and what to look out for so what we want to do inside of this folder we're going to create a new c plus class as we've done a few times now this one is going to be of type user widget which i think is at the bottom where it used to be if we can't find it here then what we can do is go to all classes find the user widget and there's only one version and this is how we're going to display the information in the world to kind of show the progress of the player so we're going to create this one we'll press next and i'm just going to call this one rollable widget and obviously making sure it's in the game folder when i mention there's going to be a compilation error it's actually a slightly different one on top of the directory issue that we're about to face when we press create on this one so we're actually going to have to fix two things and this is very specific to user widgets and when you create the blueprint derived version of them but again it's very easy to fix something that has always kind of been in the the engine for as long as i can remember just something you need to understand how to work around or solve ideally solve another sponsored by moment as this class seems to be taking quite a while to load so i imagine you're sat here not doing it too much right now but if you did want full access to this project and many others that i create on the channel for all of the projects i go through i'll always upload the resulting files or on longer projects where they're kind of midway through their progress i'll upload the template projects if i use any as well so you can get early access to the final versions of the tutorial projects as i'm going through them you can get all of that through patreon so if you wanted to support the channel allow me and help me to keep creating content like this then definitely check out the patreon page which i will link in the description below but it does mean that you get the option and chance to look at the different tier rewards and see if you can make use of anything like those complete project files if you wanted to download those and work with them and as always to all of the people watching this and who are already supporting me on patreon a huge thank you to all of your supporters they're really really growing much faster and bigger than i expected and it's allowing me to do some strange things like this long form video that i'd never really considered doing before so hopefully this proves to be useful and it's only because i've got that flexibility where i've got a little bit of the support from patreon which allows me to dock some of the usual freelance work i'd be doing that i can spend a lot more time creating something like this and this has taken a lot of time to create even though it's only going to be a two or three hour video that you might end up watching this has taken days so far to get fully recorded and edited as i'm going through this okay so here we go we have the compilation error which i was expecting so it doesn't really need to be said but we're going to say no we're going to take the old route back into our ide and we're going to start fixing this issue so i'm going to hide this i'm going to go over to again the explorer will need to be exposed for me to find this and we're going to go into the rollable widget dot cpp the code file and you probably know what to do at this stage so we're going to get rid of this now that is the first and only problem that we'll see for a little while at least until we're back in the editor uh we can actually do the one and only thing that we need to do at the moment in our header file so this is a very kind of empty class when we're working with user widgets you don't generally do a lot of stuff in here this is another one of those things where it's so so visual and there's a really nice link between the visual components and the blueprint graph the blueprints actually going to look a little bit different to what we've seen in the other classes and you'll see why as we go into this if you haven't used widgets before but what we want to do in here is basically we're going to create one function which is going to be a public function so we need to put this in the public section again we'll leave some space above because we will need to include a u function in a moment but we're going to call this function and it will be of type void and we'll call the function set item text so we're making a custom function here this will need two parameters and if you just consider what this is doing so remember this is going to be getting called from our game mode and we already have those two integer values that we know need to be displayed to the screen and that's what we're going to be passing in here so we're going to have an int 32 for the items collected and we're going to have an int 32 for the items in level okay so the reason we're doing it this way is this has been set in a way that i want this to be printed out when we show the information to screen so we're going to say items collected out of items and levels so it's going to start saying you've collected 0 of 10 items or something so there is a little bit of logic behind the way that these have been defined in the order for the parameters just makes it a little bit tidier to work with them a little bit later now the function type we're going to give this i'm going to give this the u function property of blueprint implementable event like so so the difference here is this doesn't have any c plus plus implementation at all we've put it in a public section of the class which means other c plus classes like our game mode will be able to call this but they will be calling the event to be fired in the blueprint version we're back to make so we don't create any implementation we leave the code file can be left completely blank and we can compile this and go back over to the editor and we can take our first look at working with widgets so make sure you compile this control shift and b to compile restart the editor if you need to if this class isn't showing in the editor because of the compilation error and then we can start working with our first user widget back inside of my editor the rollable widget has actually shown that time i didn't need to restart the engine but again do pause here and restart it if you're not seeing this as long as the compile has gone through successfully you know you don't have any issues now this is where that other widget specific issue with c plus plus is going to come in so i wanted to show you both ways that we can do this to begin i'm going to show you what a standard blueprint widget should look like so again you know what to look out for so we're going to right click inside of the game folder we're going to go down to user interface and select the widget blueprint option i'm going to leave this one i'm not going to rename this so i know to delete this in a moment and what we can see here when we open this this is what we want to see and this is what we want to see when we create the version from a code file so what we should have if you're new to widgets unlike blueprints which just have a graph we actually have a designer and a graph so the designer is where we put in our the actual user interface stuff so things like progress bars health bars buttons text all of those good things are going to be just here then this is again where the we can really leverage the the power of blueprints and what this will afford us anything which is ticked as a variable just here inside of the designer so both of these are ticked as variables note the names to the left hand side here we've got progress bar and button if we head over to the graph section we can see that under the variables we have button and progress bar so anything exposed in the designer is accessible through the blueprints and we can do anything we want with these here so we've got options for things like for the button we've got the on the button clicked pressed released and so on so we can set them up visually here we can even do things like creating animations to scale them and make them more juicy and looking good and then we can play those animations and we can access their variables and implement functionality when they're clicked all within this blueprint in comparison in c plus plus you're not just going to be able to look at this canvas think about where and what you need to be placed you're going to have to create and define all of the buttons all of the different components in code you're going to have to then create them in the code file you're going to have to then make the bindings and everything through the code that way as well and it's just a lot more cumbersome on something which is so so visual and usually you can get away with this for menus and things where it's not going to be taking a lot of performance hits in a game this might be different for more complex inventory systems then there's definitely an argument that c plus will be the better place to set up a lot of that structure but for something simple like this this is definitely a kind of blueprint focused approach that we'll be taking so this is a quick overview we'll be looking more at this as we go through and use it but this is what we should be seeing now what we're going to do is we if we go back and follow our standard approach to going to the games folder in the the code classes here we're going to right click on this and create a class based on the rollable widget again as we've done many times before i'll name this one wbp so it's slightly different naming convention for widgets we've got wbp for widget blueprint and then underscore the name of the widget so i'm just going to call mine rollable widget will be fine and then if we click the create blueprint this will work kind of but it won't give us the results that we want so you can see here we've got i'm not sure what it thinks the class is i've never quite worked out what the problem is behind this but you can see that we're not getting the correct layout so we don't have the designer or graph option it knows what the correct parent is so we can see the parent class it knows that it's a user widget but we're not getting the visual aids and things that we really want so what we can do there are two ways around this we can either create a new class like we've done here and then manually set to the parents so if we go to the graph the class settings and then change this to be the rollable widget the c plus version then we get the widget setup as we want it but we also have the parent setting here which means we can override that function which is going to be the important thing so i'm going to go to the function override find our rollable widget function which is the set item text and this will allow us to get that function call from the game mode alternatively we can use the one that we have here so again we're going to change this to a user widget so we'll re-parent this it'll say that this is going to be losing some details which is fine and then turn this back to a rollable widget and in fact that hasn't quite worked as intended i was hoping that we'd get the full user interface here so i think what we're going to do in this case is we're actually going to close this we'll go back to our menu we're going to press f2 which will allow us to rename this function or this class i'm going to cut this and then just delete that class altogether and instead we're going to then f2 paste that name back in and remember that inside of this widget class we've now reset the parent class to be the rollerball anyway so this is going to be a perfect start so the main thing is you're going to have to get used to that kind of process when working with the c plus 2 blueprint version of a widget probably the the safest way to do it is we just saw the other way it didn't work this time is to create a brand new blueprint widget and then go in and change the class settings to be your parent class from the uh the code file that you've created so what i'm going to do is we don't need these interface components now so i'm going to get rid of those we'll hit compile and we want to make sure that we get rid of any button calls that we may have made and we can start looking at setting this text event when this is called so we're now at the stage where we're actually incredibly close to getting this finished and it's going to come down to which order do we want to go back and kind of fill in the gaps that we've had to leave until later so my approach i think we're going to finish the widget first we can kind of set up the visual aspect the informational side of things so that we can start at least displaying something to the player through the designer and then put a little bit of code here in the graph and then we're going to go through the items and the game mode to sync everything up at the end so for the designer all we want is a text component so again very simple we're just going to drag in a text component i'm going to set the anchors over here to the middle so we're going to center align this by dropping the anchor option we can see the anchors over here at the moment is going to try and align it based on the top left corner i'm going to make this the middle and then i'm going to add for the x which is x is sideways or we can control the x position here i'm going to set the alignment to 0.5 which is going to drop this over a little bit but then if we set the actual position to zero we can see that's perfectly central in the screen and on the y i'm not too worried where this falls as long as it's not going to be blocking the gameplay now a few considerations unless we change the sky the background which isn't a huge part of the topic everything is quite bright so i'm going to set the text to be a darker color we can set the color and opacity to a darker gray maybe not fully black but a nice dark gray will be fine there and i'm going to set the font so we can change the font and the typeface and everything here the font if we had any others we could change but we don't have it installed so roboto is fine i personally think that the light roboto looks a little bit better and we can change the size so this is going to be a little bit bigger and easier to read something around about 48 maybe 50 would be fine and then the final things we want to tick this size to content because at the moment we can see the content size box is slightly outside of the actual text and then that will pop the text back into the right position and we have an option here a place that we can actually fill the text and i'm just going to set this to some default to kind of show us roughly what it's going to look like because i'm going to say items collected 0 out of 0. now we're going to make this dynamic in a moment we're going to set the the code we'll actually be selling it to say this but this just gives us an idea of what this is going to look like in the widget so this is going to be our whole screen space and then at the top when the game mode creates this widget it's going to say items collected x out of the number of items in the level now remember one of the really important things is we can only access designer properties if we have ticked them to be a variable and just for cleanliness i'm going to set this to be text collected for the the name just so that when we see this in the graph we know exactly what this is relating to and that's going to be a good habit to get into for any kind of widget component you work with setting things up to be like button quit button start button retry it arranges everything alphabetically that way based on their type and it's very easy then at a glance to see what you're working with in the graph because otherwise if you remember when we just dragged things in it will name them based on the number that you've uh which number of button they are so otherwise we'd be looking at button one two and three which can be a little bit more confusing so i'm just gonna get rid of the uh the buttons though we might need those make sure this is a variable and our text is ready to go and then quite simply what we want to do is we're going to control drag our text component so again as i said this is how we edit or manipulate the visual components that we've created in the designer and as we've done in other blueprints remember when i said a little bit earlier that anything that we see in the right hand side here similar to the rotating movement component anything we can see here we can usually expose to our blueprint we'll do the same thing in this case which is we want to change the text variable so the text information that we have here we want to change that to be based on the dynamic changes in the game so we're going to pull from this we're going to look for the word text or set text is exactly what we want to do we can see we have a few options we don't want to set the transform or policy text collected not relevant that's the function call that we have just here so the only other option is the widget set text text so it's taking in an input so this in text is going to be what we have here and we want that to be based on a collection of the integers we're passing in plus a string that we're going to need to append so we're going to right click in here i'm going to find an append string node and basically this append node allows us to create multiple different inputs it's going to bind all of those together into one long string or one long piece of text and then if we drag the return pin into the input pin we can see it gives us the option to convert this so it's going to do a conversion from text to string and we want to plug the end result of this into our set item text function and then we want to build this string based on what we have here so we know the first part of this i'm just going to copy and paste the items collected is the first part which is never going to change so that's going to be the first element of this string that we're building then we can include a space at the end of this to make sure that we put a space the second element will be the items collected so that would be at the moment zero out of something and then that kind of hits us towards the element c which is going to be the out of so we need a space out of space just to account for spaces as the item integer variable won't provide those for us and a lot of moving to keep this as tidy as possible but the final thing is we're going to drag from the items in level and that will be argument d so this one i make a string which will read items collected number space out of space number is basically what's being created there that's being converted to string another learning opportunity for you here have a look into what the differences between strings f names and text are inside of unreal so there's actually three different types we're only using two of them here in a very short vague answer different parts of the unreal engine will use different types usually because one type is more flexible or space efficient than the other so the less flexible ones are going to be more space efficient and so on so we need to sometimes do these conversions so have a look as i said a good thing to know is going to be the differences between f names strings and text but with all of that said that is as complex as our widget needs to be so that is actually all of the functionality set up so now when we have this function called whatever we were displaying here is going to be updated to have this custom string based on the values we're passing in based on what the player's been doing in the world to collect those items so the next thing the next logical step that i would say that we're going to take is returning to the game mode so if we navigate to our code folders and we'll go into the rollable game mode we now have that user class ready to go which means we can start passing those function calls and things across and also displaying it to the game which is going to be the most important thing just a quick example actually i think it's going to be useful to know how to do it in both blueprint and c plus so let's do it in blueprint whilst we have this going uh let's open the bp underscore game mode i'm only doing this because the approaches are actually quite different when working with widgets and calling them depending on whether you're doing it in blueprint or the c plus plus code and this is something i think you will do quite a lot it's going to be useful to know both so at the moment we have a widget obviously we don't have anything telling it to be displayed so the way that we do this is in blueprints we're going to say create widget and we want to pass in a type of widget here that of course is going to be the wbp underscore rollable version with all of our visual updates made and a lot of people instinctively and sometimes will just forget to do this always remember this is only half the step if you press play now we've created a widget but we haven't done anything with it we haven't told it to be anywhere so what we want to do is pull from the return pin and we're going to say add to viewport okay so this is just going to the viewport of course is what we're looking through this is going to take that thing that we've just created and place it in the viewport so if you press play now we still don't see that so i think this is just going to be an issue where we need to restart the editor not really worth doing it for this so instead of doing it in the game mode for now it's just the blueprint version of this hasn't been called for whatever reason what we want to do is i'm going to jump into the player class it doesn't really matter where we call this from we're only going to be doing it in the game mode c plus class because that's where we're going to be passing information to him from you can do this from pretty much anywhere so we're going to paste this back in to the player class basically as long as this is done on the begin play just to show that without having this hooked up again there's going to be no widget so this is only half the step and then if we plug this in so that thing we've created is now being told to be displayed on the viewport we can see here we have the items collected zero of zero so that was working like i said i think it's been a while since i've restarted the editor we've done a lot of different um compilation in adding different classes in i know that we've definitely implemented the begin play in our parent class so it may just be that we need to recompile something but like i mentioned we're not actually going to do it here anyway i just wanted to show the process so that's the blueprint process so we're going to delete this we don't want that being driven from blueprint but that's how you do it if you ever needed to come back to that in the future so if we hop on over to the gamemode header file we can now start implementing the variables to allow us to create that in our code as well so remember we've left ourselves a to do section here this is basically where we want to create the information about the widget that we want to display on the screen we couldn't do that before because we didn't have the class types that we know that we're going to need to include with that in mind we also know from experience by this point that the engine won't know about that class type either because it's another custom type and because we're in the header remember we can do a forward declaration we won't be accessing any of the functionality or properties inside of the header so we can use that lightweight forward declaration and remember we call it rollable widget it's a u class type so we're going to say u rollable widget so that has now been forward declared and we can use that below now for this we're actually going to need to declare two things when working with widgets the first will be a t sub class of and that will be a generic class of user widget and i'll call this one game widget class so this basically allows us to define a certain type and doing it this way allows us to expose this to the editor so if any time you wanted to change out one widget to another this will give you the drop down option to switch and choose which type of widget to display that will only happen if you include this u property so we need to make this edit anywhere and i'll put this in a category named widgets so this isn't the thing that we're actually going to display to the window this is just allowing us to define the type of widget that we want to create and display later so that's why we need a second type of variable and the way that we'll do this one this is going to be specifically of the u-rollable widget and i'm going to call this one game widget so i always kind of try to distinguish these two we've got game widget class to show that this is the the class that we want to expose or leave as an option for somebody to choose and then the game widget which will be the one we'll be displaying and this can just have an empty u property as we won't need to change anything here so they're the two things that we need to include in our header and then if we go over to the code file we can now come back to that beginplay function and we can start implementing the logic to actually display this to the window like we've just done in blueprints okay so slightly bigger bit of code here so again on screen for you to copy down at your convenience and i'll go through line by line and explain exactly what's happening first two things is that we're going to need some includes again so if i select this and alt and enter we can see that we need the blueprint user widget so i'll allow it to include that for the create widget function of course we're going to need the include for the urlable widget so again we'll include the urlable and finally and the final error was just a typo that i had that is updated item text and the function name is update item text okay so those includes done keep these on screen as well so you can see the includes that we'll need we'll go through one step at a time so the very first thing that we're going to do is we want to check if the game widget class has been selected so remember this is the one which is just being exposed to the viewport so that we can select the type of widget we would like to create to avoid people forgetting to do that and trying to create something that doesn't exist we're going to put this into an if statement and we're only going to try creating the widget if this has already been defined if not then we're not going to do any of this and we just won't have a widget so then if that has been selected what we want to do here is we're going to set our game widget which at the moment is just a variable we're going to set that to be the result of a cast to the u rollable widget and we're casting against the function return of the create widget again we've seen this owning object world context so we're using the current world as the owning object context and we're casting against the game widget class so we're making sure that at some point in the hierarchy the class which has been exposed in the editor is derived at some point from our custom u rollable widget so this is now filled this with a variable if that cast has been successful so if this is any other type of widget class such as the default user widget something that will fail but as long as it derives from the rollable widget then that will be filled with a value so the next thing is a kind of security check again we're saying if the game widget which is basically saying if it is valid if it has a value in it the other context for both of these would be isn't equal to null pointer is essentially what we're saying if if it isn't equal to absolutely nothing then we are okay to go ahead generally people find this a little bit easier to read and just quicker to type so again this would be isn't equal to null pointer so if this isn't equal to absolutely nothing then we're going to allow it to try and create a widget so if we do have a game widget then the final steps very simple again so we've created it now so this is like the first step we did in blueprint which doesn't do anything but it just creates it the next thing is we want to get our game widget and add it to the viewport so that is the second step that we saw in the blueprint version so now that's been added to our viewport we can now see that the first thing we want to do with our new widget is call our update text function and we'll access the functionality to update the text in here now so remember by default it's showing that the items collected are going to be zero out of zero so i'm gonna we'll want to update that to reflect our items in level value that we've tracked a little bit earlier this again is very simple so we're going to call it the function remember that we've set this to be a public function on the game widget so we're going to call the set item text and remember the two parameters that we've exposed to be filled in are the items collected out of items in level which if we just hop back over to the blueprint quickly is going to call this function and it's going to provide the items collected out of items and level create this string and pass that to the text and then the final thing so that we don't forget to do that here is we're going to need to update the item functions in a moment but when that's been done we want to also make sure that the update item text is called here as well because of course otherwise we're never going to update how many items have been collected so every time something is collected we're just going to recall this which is going to reset the text in our widget so that is everything in the game mode i think that's nice and simple so we're checking if a editor widget type has been provided so if this is left is none then this would be false and we won't do anything if it is we're going to check against that type to make sure that it is a type of rollable widget and again if it is then we are going to add that to the viewport and update the text to show us the current items that are in the level and to begin with this is just going to say zero out of however many items we have in the level so if we compile this we can kind of test this one step at a time we can make sure that we at least have the widget showing now and we have some kind of uh information to feedback to the player once again back over in the editor i have a feeling at the very least we might need to do a hot reload or recompile down here we can see now if our game mode code updates will take place and show the widget of course they won't because we need to go to our blueprint game mode so the first thing is to check our newly exposed variables so we have a widgets category that we've created we have our game widget class which we want to as i've said is going to default to the you user widget and anything of that type and specifically the rollable widget and we want the widget blueprint rollable version so that's going to be the type which will be cast against and then it's that other variable that we haven't exposed to the editor which will be created and added to the viewport so if we press play that is working which is brilliant so we can see that the begin play issue here wasn't actually going to be a problem that is being called and not only that but we can see that it's picked up we have exactly four of these items in the world so we're now one step away from getting this finished minus a little bit of visual flair and a kind of visual update if we wanted to do that so this is good i like this what we're going to do is we're going to go back in to our items class we want to double check what we have going at the moment so we've got the visual thing here which means i think all we need to do is that function call so if we go into the rollable item base and we have our collected function we know that this is working we're gonna go to the code file we have one to do here this is really exciting stuff we need to get rid of one to do and we want to get our game mode if i sound unreasonably excited i've been recording this for three days i've had loads of system problems and recording what i thought was going to be just a simple two or three hour tutorial has taken much longer than expected but i'm not giving up so one step away is incredible at this stage final step is to get our game mode now we've seen similar things to this in the past it's going to involve another casting to a specific class which of course we already know what that is so what we want to do is we want to create a new variable of type a rollable game mode or what we've called hours game mode bass this is a pointer to the class and we're going to call this one game mode you could call this gm or something like that people often shorthand this type of thing doesn't really matter too much as we're only going to be using this once and what we want to do here is we're going to say that this is equal to the result of a cast so remember whenever we want to check against another class to see if it is of a certain type we're going to cast and we're going to say that this is the a rollable game mode again or a rollable gamemode base then again we've seen this type of thing before so we're gonna need a source we need the world context first of all so which world object is the game mode relevant to because remember as i mentioned a little bit earlier i touched on every different world map or level whatever you want to call them will potentially have their own game mode so again we're going to use the built in get world function and from this we want to get the authorized game mode definitely outside of the context of this short course so the author part is just relating to some of the networking stuff whether this has authorization as a server game modes are server-side only so far more technical than we really need to be getting into for the single-player game but this is just how we return the current game mode in the world in c plus and as we've seen before we want to make sure that we're never trying to access or call a function on something else unless we're completely certain that we have a valid reference to it or a valid object which has some information filled within so what we're going to say is another conditional f check so if and then game mode so as we've done before if this isn't equal to nothing if this cast has been successful and we have a uh a stored value to the returned game mode now then we can definitely safely call our item collected function and there we go so that is the final thing remember they're already calling the collected blueprint so this is doing all of our visual stuff the blueprint is making sure that the visual content is handled first or kind of in order before being destroyed and amid that logic remember it's doing a callback to the implemented version which is where we're going to be doing our c plus communication updating the things being handled in the game mode and the the kind of state of the game in that way so we can now compile this this should be our last compile for our code and we can test that everything is going to be working together so back over in the project we can see if this has gone through immediately i don't think anything's been big enough of a change there that we'll need to recompile or anything we can come in and there we go so when we press this now the item is calling the function to the game mode and we can see that we've got four of those four items picked up remember if we alt and drag when we're using the move tool or any of the other kind of transform tools then we will make a copy of what we're using here we can pull in another two just to test and we should expect this to now automatically update to show that there are six items in the level potentially to collect and it does and again we can then double check that we can collect all of those if i didn't roll off the side but the main thing i think we know that was going to work we can see that this will update to sync the number of items available to collect with the number of items we've actually successfully gone over and collected so we've got some nice communication between different classes we've got the whole structure of working with widgets sharing the logic out between a bit of blueprint and c plus plus code and we've got a very simple game going here so i suppose the last things that we could do as this is intended for the people kind of new to the engine and kind of just working your way around the engine as well we will do that somewhat visual pass so a nice thing to know about here is we're we're still using a lot of kind of boilerplate materials we've got this grid so we can start by creating our own material we'll do that by coming into the content folder again we'll keep this nice and tidy we'll create a new folder named assets and inside of the assets folder i'm going to create another folder named materials and inside of the materials folder we're going to right click we're going to go to material and i'll call this one m so the naming conventions for materials is m underscore and then the name of the material and i'll call this one flat it's just going to be a flat shaded material nothing spec special we're not going to use textures or anything you could have a m underscore texture or m underscore grass or whatever you're going to be doing we will be creating some instances or variations of this and i'll show you how we can expose those and work with different types of materials so by default we get this horrible kind of shiny not quite fully shiny material going on so what we're going to do we want to override the details in our material to begin the first thing we can change the color a few shortcuts for this now as with blueprints we can search for certain things like color which doesn't actually exist because colors are basically a collection of their float values so red green and blue is a float so it's actually what we're looking for is a vector 3. so we want a constant vector3 we can see by default this is black if we click into this we can either change the value here so we can up the r so the red float we'll get a red color or we can double click and have a full color wheel picker here so we can default this to something slightly more pleasant like a blue make it a little bit easier to see the updates and plug that in so that's the kind of slower way to do it just so you know how you can search for things something to get very familiar with if you're going to be using this a lot is the shortcuts so to recreate this we would say we'd hold 3 on the keyboard not the numpad and left click and we'll create a vector three two for vector two one now the way that we've created this isn't going to be very flexible so if we take a quick jump ahead in topics we're gonna come back to the browser we're gonna right click on the material and we'll create something called a material instance so let's say that this is going to be our red version of this material so we'll call this m underscore flat red underscore instance so this lets us know that it's an instance of apparent material the viewpoint for this one looks a little bit different it will show us what the parent is and if we expose anything it would also show us what variables can be exposed or edited through those exposed properties now to expose something we can come in back into the parent and we will right click and we'll convert this to a parameter when we parameterize this we can give this a name so we'll call this one color and if we save this and apply it we'll have a little bit of shader compilation going on we'll go back to the instance and that means we can now on the fly update the color of the material now this is a really good thing with material instances if i drag this down a little bit go back into the main window let's grab our material over here and place this on the floor and what we can do is we can update this in real time and we can see that is mirrored to where this is used so in fact let's create a kind of gray dark grey floor nice clean looking gray floor and i'm going to rename this one to kind of match that so we'll say m underscore flat gray so that's going to be our gray material color so that's how we're going to use these parameters from our parent that we create here in our child or the instance that we want to make a little bit more flexible so what we can do just another shortcut on top of this so at this point we've got three and left click we'll create a color and we'd have to convert that to a parameter now a parameterized vector3 is something you use quite often so it's going to be useful to know that if you hold v and click you actually immediately create a parameterized version so you can see that we didn't need to go through the color and then converting it to a parameter we can just create that with v and left click now in a similar way remember i said one and left click gives you a single float known as a scalar parameter we can also press s and left-click to create a parameterized scalar so i'm going to create one of these for the metallic specular and roughness so we need three scalar parameters okay with those we just need to hook those up and you can see i've named the met spec and rough and what we can do now again rather than changing anything here because the other thing about doing it in the main material is the compilation for the shaders and the updates can take a little bit of time so if we just compile and let this compile the shaders once the ideal way is to work from the instances of our materials because like i've said this is all real time so if we tick these new parameters we've just exposed we can up the material or the sorry the metallic value of this and again we'll see that this is immediately updated in the world as well so if we wanted to see what this would look like on the floor we can play about with the shader values for the metallic the specular value i think this is for the roughness and the specular so you can change all of these now at your leisure so i'm going to set for me i quite like the the roughness being pretty much full we could play about with something having i think for the floor we'll keep this completely rough actually so i'll set this to one and roughness xeron metallic and that is the floor grey done so what we want to do now is we have our material pretty much ready to go we can come back and play about this later if we find that this isn't going to look very good but what i'm going to do is press ctrl and w on the grey instance to create another instance material and i'm going to rename this one to let's have a white ball so flat white we won't make this completely white maybe like a creamish color or something supposed very light grey is what we're going for there we can come in to our player class now so i'll use this for the player so we'll go to the blueprint we'll go to game player and in here we're going to get the mesh and again so that we're not using this um checkerboard material the default material we can change this to the white instance of our custom material so now if we press play we have a ball with our own custom material and we can start playing around with things maybe we want the player to be somewhat metallic and somewhat rough kind of like a polished metal or something polished metal marble rather than completely glossy marble so there we go we've got a kind of polished metal and that is going to take in the lights and everything fancy in unreal 5. do all the fancy reflections because we have that little bit of kind of pbr material going on though physically based rendered material and the final thing i think i'm not a huge fan of um too much emissive just for the sake this kind of tron style cube is a little bit gauche so we're just going to come in and we will once again create another material uh control w from the flat grey inst and i'll call this one let's have some nice yellow cubes okay so for the cube we're going to drag this down to yellow so again you can see very very simple to update is the main thing here really speeding up a workflow making this as convenient and painless as possible let's say that we're picking up some blocks of gold so we're going to give this a nice metallic value very very low roughness value that's gold that's good and then if we go back in to our item class so we can select any of these go to bp underscore item base go to the mesh go to our material i'm going to change this to the flat yellow it's not really a flat yellow anymore it's a shiny yellow but there we go we've got some golden cubes which who doesn't want golden cubes i think one thing here is maybe the camera could do with a little bit of a change so we're just going through a phase of making the game although it's simple look and feel as good as possible so for me the camera is a little bit low i don't get a very good view of the whole level which i think for something as small as this we could probably fit a lot more into level that feels a little bit better and we now have a shiny silver ball picking up shiny golden cubes nice and simple so we've already started getting this looking somewhat better one thing i think could be nice for people as well to know about is the sky sphere and how it has some kind of flexibility to play around with this quite easily so at the moment this is all very realistic we're going for what is essentially a floating gray platform with some golden spinning cubes on it so i'm not sure how well the the clouds and the sky sphere really fit so what we're going to do is we're going to stop the colors being determined by the skylight or the sun position so the sun position is our light source which is just a directional light if we rotate this and if we tell the sky sphere to recompile or refresh then as we're looking further down we've got like a midday light and if we rotate this to look up then it's going to be closer to night time like so now not a huge fan um just for like this type of game at least having that so i'm going to untick that which means we now have full control over how the sky looks the first thing is i'm going to lower the value for the sun brightness cloud speed and opacity we don't need any of these so we kind of clear up the sky sphere this way it looks a little bit cleaner a lot less going on then the next things we can do is affect the color of our sky so we've got the horizon falloff the zenith color and the horizon color and also the clyde color can all come into play with how this is looking so we've got the dark blue at the top and the lighter blue towards the bottom so i'm going to lower this again i'm going to make this a little bit darker a little bit more of like a flat gray i'm going to copy this color here the hex srgb because then we can double click to open the other one and paste this straight back in and again we now don't have any of that gradient so that is just a lot less going on for something which looks quite simple it seems to fit a little bit better the other things that we can do we don't really need the auto exposure so if you notice that the color of the game changes as you press play a lot of people get a bit annoyed by that so if you ever wanted to know how to turn that off we're going to go to project settings we're going to go to auto exposure in the search panel and we want to untick the auto exposure so this now means that it will kind of evaluate what this will look like and it should look pretty much exactly the same from when we enter to when we press play something seems to be overriding that maybe in the post process or perhaps the camera or this might be one of the first bugs that we encounter in unreal five so let's just double check we shouldn't be getting that pretty obvious change so we're going to go to the player blueprint i want to check the camera and we want to make sure that this also doesn't have auto exposure because it can be controlled in two places which would be the project settings and the camera settings so it's not ticked on it's not set to be on by default but we're definitely getting we can see it brightening up and trying to adjust as we play which ideally we kind of want it we want to know what we're working with in the editor is going to look the same as what we're going to be seeing in game one other way that we can solve this then since that doesn't seem to have worked in unreal 5d taking that from the project settings which it used to in unreal 4 we can take this minimum and maximum brightness and we'll just set this down to i think it's zero to cancel this out nope don't do that that makes it very bright so it's going to be one to make sure that both of them are always the same and there you go so you can now see that nothing changes from when we're in the the map here there's no slow kind of easing into a brightness so that's a lot closer to what we wanted to stop that from happening and then the final thing is we've got it showing that it wants to rebuild the light so these are kind of non-stationary objects anyway they're rotating so there's two options we can either come in and build the light as it is now by going to build and build lighting only that will take the light at its current position and bake everything like the shadows and stuff in and that will get rid of that warning uh when this building process is finished uh we can see that makes it a lot darker because it has now accounted that the the essentially the sun is still pointing up so it's quite dark so we can bring this down a bit um and give that a bit of an angle to make it look pretty cool again we might want to build this or another option is if we make this movable then that won't have any issues it would just take that kind of real-time lighting into account so this is now all being processed generally you're not going to want that all of the time it's going to be a lot more performance heavy but for something like this i think we can afford to render this at real time or like this at real time um and then you just want to play around with things like i've noticed that since we've changed the sun that is now a little bit washed out so you might want to change the angle which this is facing um i don't know if having a second sun or something would make this look better and this is where my kind of programmer art is really going to start kind of standing out but these are the things that you can go ahead and play around with so setting up the materials dragging in if you've still got your place actors you've got a lot of different options for lights so you could add some interesting lighting by bringing in different lights over here changing the color giving it some kind of unique style to your level this way with different lights and again dragging these around this might look quite cool if you were to go back into the project settings and turn on the the lumen options again if you if your system can afford that so we'll look back at the global illumination we need to turn this back to lumen so this is just letting me know that the reflections which need to be working with this have been automatically enabled which are if we remember we've also turned off earlier the reflection method we set that back to none so it's been set back to lumen again and this when i kind of account for those in our project i don't think it looks that much more amazing on this kind of basic of a scene but it's an interesting thing to play around with so yeah go wild add in some lights add in some different kind of areas or create a different stage bring in some meshes and play around with the project okay and in the end after playing around with some materials i've turned the material back to be a flat material if you can see the flashing now i'm not sure if this will come across in the video this is part of the system issues i mentioned my gpu seems to be having some serious issues at the moment so ignore those that is just my gpu again nothing to do with the project or unreal this that happens mostly when i play games but what i've been doing is just playing around with different lights setting up a few different lights just to make it look a little bit more interesting we've got the nice reflections and stuff happening set the materials for the cubes to be back to a flat yellow with a tiny bit of metallic on them which comes through uh the roughness takes priority some lighting and cell again all of this to be rendered at runtime so nice and simple very simple small level but i think we can still make it quite fun and interesting to look at we've got the jumping we've got the moving we've got all of our mechanics now in and ready to go and hopefully you've learned enough that you can start extending this if you wanted to playing around with different mechanics and you have hopefully a good understanding as an intro to the unreal engine c plus and a little bit of blueprints with that all wrapped up i hope that you've enjoyed the process of creating this small game and you have plenty of things to take away from what we've discussed in this video as i've mentioned if you wanted to know more about these topics there's loads of different learning opportunities to take away from them and if you wanted to support the channel the content i make and learn all of that information or the topics around those like i've mentioned not necessarily the c-plus plus then definitely consider looking at the course provided in the link below we create a very similar game to this again it's a nice way to introduce people to the engine don't need to worry about things like the the art side as much the animations we can get very much straight into the logic how and why things work so that's why this rollable game is something i've used a couple of times now including in that longer kind of full introduction course provided that i've mentioned if you wanted to check that in the description down below as i said that would be greatly appreciated it helps support the channel and hopefully give something back to you in the form of those 10 to 12 hours of content for you to go through and learn as much about the engine as possible in a relatively short amount of time likewise if you enjoy this sort of content be sure to subscribe and hit the notification bell to find out when any of the latest content on the channel goes live and if you weren't looking for a longer course to go into but did want to support the channel and the work that goes into creating this sort of content then again do consider looking at the patreon page and hopefully likewise that will give you something in return for your support of the channel as well i try to make the reward tiers as beneficial to people as i can think of based on the content that i create and if you extend the content from this or just make something based on what we've covered here then be sure to head over to the discord again link in the description below completely free discord open to everybody you can join that share your work and let me know what you've created for many of the content provided on the channel or this video as ever though thanks for watching and i will see you all next time
Info
Channel: Dev Enabled
Views: 159,136
Rating: undefined out of 5
Keywords: devenabled, devenabledAssets, gamedev, game dev, game design, tutorial, tutorials, unreal engine tutorials, ue4 tutorials, unreal engine 4, ue4, pluralsight, course, learn, education, ue4 content, ue4 developer, udemy unreal, unreal developer, game Mechanics, ue4 C++, unreal C++, unreal Engine c++, ue4 C++ tutorial, unreal engine 4 C++ tutorial, core game development, unreal development, unreal engine 5, unreal 5 pc, unreal sensei, learn UE5, UE5, beginner UE5 Tutorial, Beginner C++
Id: KQgOqyYoHAs
Channel Id: undefined
Length: 202min 14sec (12134 seconds)
Published: Sat Jun 12 2021
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.