Unreal Engine C++ Fundamentals - AHUD, UUserWidget & UWidgetAnimation

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments

Dude, these tutorials are so helpful, I recently got into UE4 C++ and I found your channel through this post and I started binge watching all of your videos. The quality is amazing Thanks a bunch!

👍︎︎ 1 👤︎︎ u/Ragnato 📅︎︎ Mar 17 2019 🗫︎ replies
Captions
[Music] hey guys this is Wojtek and today we're gonna take a look at adding in some widgets specifically to allow us to create combos with little animations as we interact with our environment by hitting it to accomplish this we're going to override the hug class and have it be sort of part of our default game-mode we're also going to create a new user widget that's going to contain all of this sort of confirmation and then lastly we're going to manipulate our widget using widget animation elements so let's get started alright folks so let's get right into it we're gonna go ahead and create a couple of new classes we're gonna create a new HUD class and you use your widget class time we're given extend for our UI components so I'll just go ahead and do that before we before we get started so I'm just gonna create a new class and this is gonna be part of our HUD so it's gonna inherit from hot h we're gonna drop this into a new folder called UI I'm gonna call this guy you know it's gonna be in game in game HUD so it's gonna be the primary HUD for all of our you know health bars combo attacks and sprint stamina measurement and all of that good stuff so let's go ahead and create this class this is gonna take a second okay so we have our class generated and now let's just go back to the editor for a quick second and generate our user widget class as well so the HUD class is going to be our container of widgets so think of it as sort of as the the holistic representation of all of our UI components and the widgets are going to be the individual pieces that you know comprise our various our various functions so we're going to look for a user legit as our base class there it is and again let's drop it in the UI folder and we're gonna call this guy our [Music] our COBOL widget so there's our class all right so we have the two classes we're going to be working with and we're gonna start off with our combo widget class first just because in game HUD inherits it and our player character is gonna care at the HUD so just kind of we're gonna work in order this time and first things first we want to create a constructor this is gonna be our combo constructor the only thing we just have to be aware of as you come budget is that the default constructors for the widget components are not actually empty they taken a Const of an object initializer so just make sure it turns to the Dozen a parameter otherwise you will get you know compilation issues if you're ever curious as to what these methods signatures that you're overriding look like you can always step into the actual base class for user widget and start poking around I'm just show you real quick so you can see there's our user was a constructor and there's a handful of methods we can overload and implement within our within our user widget implementation so one of the ones we're going to look at later on is things like native constructs and a couple of other ones in order to do some various functions but for right now we're just going to focus on the sorry on the constructor right here so let's go back to our widget so we have our constructor and that's that's pretty handy and now we're going to do a couple of things so we're going to create a method that allows us to update the count of our of our hits of our other combos so I'm gonna create a new method call just updated combo event and it's going to take a integer as the value you know anything fancy for that we're also going to create another method on this widget that allows us to read set the count and perhaps you know perform some other operations on our common definition so this is gonna be called reset combo no input parameters just a straight-up function and I think we're gonna stick with this for right now we're gonna get into a few other things very very shortly specifically the widget animations but let's just flush out our our component first make sure it draws on the UI and all that good stuff so the other things we need to start adding are the components of our widget that are actually going to represent our combo information so in this case I'm going to create a new property it's gonna be a blueprint and we're gonna use this interesting little meta tag you bind widget and I'll include the links to more documentation about this but this is one of those little hidden features of the UMD components that basically allows you by name to bind a property to the actual representation on the widgets so instead of instantiating let's say a text box and then sort of retrieving it from the widget and populating it locally so you can play around with it we can simply say you know view text box and bind widget is going to automatically look for this type of element on our widget with this name and I'll show you in the blueprint when it complains about not being find this now I also include information I was how you can traditionally sort of generate these text boxes but you know for the purposes of our exercise this is way faster to work with it's a little bit unintuitive as you just need to be aware that this guy does a little bit of magic and auto-binding but once you kind of get comfortable with it it's a nice little feature thank you to a gentleman on reddit who were recommending this feature I will make sure to to credit you in the blog post okay so we have our our combo we have a couple of methods and we have our initialized room so far so good so let's go ahead and go into the CPP file and now just start adding in some some of these details okay so come budget and there's our constructor so cool so there's our methods so far so good we're we're also going to include sure that's right yeah looks right what else we're going to include in here is another method because we do need to be able to initialize something similar to begin play so we're gonna use the native construct method now we're gonna override this guy sorry I completely forgot about it as I was hopping here so virtual void native construct and this is going to be used as our essentially as our begin play we're going to make some initialization directives within this I'll show you just a second drop this guy [Applause] you know counselor I always make sure to call their super methods since we're all dealing with inheritance here so things don't go don't go walk okay so update combo count what everyone do in this method well we want to bring in our text box so we're gonna say if T to combo is valid and we also want to say you know good values greater than one because we don't necessarily want to display any information for a combo if I'm just coming in with let's say you know a single hit something's gonna protect myself right at this particular level and and go from there so the other thing we're gonna do is we're gonna say a txt combo and my up complete is not working because I did not include our um G so you'll notice this data type was not being recognized in my intellisense because I was not bringing these header information so I had no way of understanding what new text box was now should be just a little bit better now this could just be slow intellisense and in official studio which I'm sure we are all used to so it's set visibility and we're gonna set the Eastgate visibility to visible and basically what we're doing here is every time we update the combo we're just going to turn this guy on if our combo box is not visible [Applause] visibility okay so far so good let's go ahead and keep expanding our logic here so once we have our text combo visible what I'm going to do is we're going to say set text and we're gonna bring in our value as part of that output so what I'm going to do is I'm gonna say F tax strew and we're gonna bring in our integer so we're gonna say where is from it value which is gonna be the first value and then we can simply say plus X gender age to X and now we've got some some additional information there so let's now take a look at the reset combo method what this guy's going to do is basically say hey X Box exists our txt combo titta so after we finish doing a combo operation and our player is finally done doing stuff we're just simply going to reset this guy and call it a day and I did forget to include super initializer which is why why this guy was complaining okay so there is our our widget definition for now and now let's go ahead and start adding in some more details to our our Hut object so the Hut object is going to be the container for all of our widgets similar to our widget we're going to say a Hut and generally our constructor now this one doesn't take any parameters by default so we're just gonna leave it as is now we're gonna override a couple of these methods in the HUD class so let's pull this guy up and just take a real quick look here so the texture there's so we're going to overwrite drawhud and as the comment here says it's the main loop for the HUD guess we call it before any any messaging and should be so close so you want to include this method this is where a bunch of you are sort of rendering details we're gonna go into the other ones we're gonna override is begin to play tick just for you know for for posterity what I'm gonna include anything on the tick right now but we'll just have later we'll just have it available for for later use so let's go ahead and over [Applause] [Applause] all right so on here we're also going to add a new function which is going to look almost identical to our widget function that's going to be called update combo count I'm sure you can guess it takes in our combo values so we have that we're also going to include a header definition for our widget components should component there we go otherwise you know recognize things and we're going to bring in our u property our GUI is going to be wickets and say T sub clause you use your widget so this is the parameter that's gonna let assign our koma widget onto the HUD which will then you know take care of rendering and displaying it appropriately the other method I forgot to include is our reset combo and this is just a helper method or our player can interact with these HUD values well you know the HUD updates all of our widget information so lastly we're going to add in our so we're going to bring in our humble widget and we're gonna create a private variable that is then going to be instantiated based on this class being available to our to our hot object okay so similar to our combo widget let's go ahead and flush out the in-game HUD CPP file so I'm simply going to instantiate our sorry our constructor and again it's not gonna do anything for right now all the stuff is available to us and then we're gonna say and that our begin play circuit out again with any methods you're overriding ensure that equal you call the parents method otherwise you know we're gonna have some weird weird issues so and begin playing we're also going to instantiate our widget object so we're going to say if our combo widget class is available we can then say combo widget equals create widget of type u combo widget and we're gonna pass and so this guy actually takes two Prem hit print so this guy actually takes two parameters if you look at the object definition so the owning object where are we going to who is going to be the owner of the spawned widget and then what is the class and perhaps we can pass in the name we're gonna ignore the name for right now so we're gonna spawn this in the world that's going to be our owner of this widget and then we're gonna pass saying our [Music] combo widget class has the other input parameter now this all went well then we can say combo widget app to viewport and we can also define the Z order here so you have widgets that overlay each other and you want let's say the combo widget to be on top of the health widget or something like that this is where you would adjust the the Z order to make sure that things are sort of layered accordingly okay so this should now take in our widget available and instantiate it so we're kind of done with the beginning now let's go ahead and add in our tick and the tick again super tick passing about seconds and what I'm gonna do much here yep likewise with our draw hood method we're just gonna leave it empty and make sure all right we're just zipping straight along for this example alright now come the actual methods that are going to allow us to do some stuff to our UI widgets so we're gonna create our update combo count takes in our value and I'm simply gonna say update combo count and we pass in our value so you can see just you know we're using this HUD as a bit of a proxy to actual words [Applause] the widgets okay so I'm just going to recompile everything make sure there's no no weird exceptions and we're gonna move on from there yeah and see this is what happens folks when I don't pay attention in just the app through as I'm typing away so the reason our you text box was not actually compiling is cuz it's you text block a little bit better so then this wonderful go away all right let me recompile and see what else we broke all right so we're all recompiling good to go I won't bore you with a couple of the spelling mistakes I had in here but visability said visibility and object initializer we're all missing eyes and you know my ESL was kicking in so let's let's move on from here so we have our widget we have our HUD we're gonna go ahead and now implement a widget so we can see that it is this is actually working and that's actually going to not blow up anything in our in our game so I'm going to create a new UI folder and here we're gonna do is when I create a couple of new blueprints so we're gonna create a blueprint for our HUD so we look for HUD now we should have our in game HUD object so we're gonna get this guy it's gonna be VP game HUD and if we crack this guy open you know there's not much going on our class settings of our parent class and you know it's pretty pretty bare and that's okay we're gonna be doing all of our work in in C++ and we're gonna add another blueprint that represents our widget so look for widget now you'll notice there's our user widget and combo widget inherits from so again pretty good home ball widget okay now to include these guys within our actual game what we want to do is go to settings world settings and depending where your pane opens up on my screen it's on the right-hand side there's a couple things going on here so there's a game mode and there was a co-op section under select game mode that had all this stuff and you'll see one of these things is our HUD class so through our game mode we are able to flip our HUDs around but in order to do this we you know we can't select it's great so we actually have to create a game mode just a very generic one so what I'm gonna do is I'm I create a new blueprint and it's going to inherit from our you know generic game mode that came with with the project I want to say 'pete game mode now all this really allows us to do is from the drop-down now to select BP game mode and we can now modify these values so we don't care about all this other stuff for right now we're gonna look at States and player States and controllers all that good stuff but for right now we're just going to simply flip our HUD class to BP and game HUD excellent so one thing done but if we start a game there's not gonna be anything on the screen because we haven't actually created our our widget definition so let's pop open our widget and you'll be presented with this this screen that has sort of the default screen size you see it's 1280 by 720 dpi you can you know make all kinds of adjustments to support the screen orientation that you need but more importantly here is that warning eye I mentioned previously so you'll notice this widget expects txt combo to be available to us with a specific type because oops we have it marked here with that bind widget you know an annotation decorator whatever you want to call it but it's there and it's forcing us to now implement txt combo so I'm simply going to take a text box or a text block rather sorry and I'm just gonna drop it somewhere here on the screen yeah you know let's go with that and this guy's going to become txt so now when I recompile sure oh is it failing 60 combo oh sorry that was the text there we go here we go sir so once we have that we compile you can see hey we have our we have our stuff available to us and our text is in the top left hand corner we should probably move that somewhere else I'm thinking no you know what just leave a different out and make sure everything works so nothing is rendering on the screen we've got our game mode and on our HUD BP the only thing we're missing is our combo widget class so those are something ever got set so on our HUD make sure we reference our combo widget and now let me start our game there we go those are sample text in the top left hand corner pretty good so now let's go ahead and actually make that text do something let's have it update as we as we punch things and interact with our with our environment okay so to do so what we need to do is go back to our player character and within our player character we're actually going to sort of get at the HUD and we're gonna do so what we're gonna do on our attack hit so let's find out basically after our montage gets kicked off we're going to make a call to our HUD and say you know increase it by some amount so to do that were first going to create in our player character a property card combo can't just go yeah let's go public on cuz everyone also have you know highest combos and things like that and this guy is going to be initialized with value 0 just to be on the safe side no one's gonna be allowed to override it we're simply gonna use it to to increase our combos and then sort of reset them later on ok but we also need to worry about resets so let's get our value going at first and then we'll look at how to reset it we're gonna use actually our timers from our previous tutorials too and to handle that so if you don't hit the combo with a specific amount of time then obviously you cancel the combo and then you have to restart again so let's go back to our on attack hit and we're gonna do is we're going to use the world they're actually bringing our HUD so I'm sorry I forgot the header file for our HUD so you I let's go back to this game start right off here a montage play plays we're gonna say game HUD and what we're gonna do is we're gonna cast it from get world and then we're gonna say you get first player controller and then we say get Hut one thing to note about this execution is this implies you have access to the local controller if for whatever reason this type of call is being made from the server you need to account for the fact that you know you may not have access to the player and there's different ways of obtaining information so just something to keep in mind when you're dealing with multi player type implementations but for our particular cases is this is gonna work just fine so we're gonna make sure our object is initialized there's a Morstan all pointers and then we're going to say current combo count by one so every time we connect with our punch we're going to add one to our combo count and then we're gonna say in game HUD update comp account and there's our current combo camp pretty pretty straightforward now resetting so let's go ahead and add in a timer and we'll drop it right here after excuse me [Applause] so we're going to create a new F timer handle and we're gonna call this combo reset handle so back to our on attack we're gonna say if it's get world good time manager is timer active so if it's active or sorry if it's not active what we want to do is actually kick it off so get rolled and set timer pass in our handle pass and sort of this object now we need a callback function so what I'm gonna say before we add this is just our character and then reset combo wha this nothin just a second our rate is going to be enough that's how we're gonna play it back it's not gonna be a loop and our our first layer I'm just making sure I have all of my properties correctly so every new possible okay now if this timer is already playing we want to do is we actually want to let's take this and we want to clear it so what I'm going to do is just say get world get time manager clear and then pass in my my timer handle now let's go ahead and add this reset combo method on our player character so it's gonna be a do we'll do it oh there's a public so let's say you function and just reset combo let's go back to our player character below this okay so what risa combo is going to do is a couple of things is it's going to by default reset our current level count to zero and it's also going to make a call to our in-game HUD so again I'm just going to call to get first player controller and now because I'm making this this cast fall a couple of times there is opportunity for you to create a little helper method you know that always gets you the HUD then you should make operations on that rather than you know sort of constantly messing around with casting and then we're gonna say in game HUD reset combo specific on there which is why that if statement is freaking out all right so if all works well what should happen after we compile this is whenever I make a hit within one second we should basically reset our combo count as we update it you know when our character punches so maybe you know know what I'm thinking about this maybe one second is too too long so he changes to serve just short to five seconds and then while we'll recompile again let me just cancel my bill here all right let's try this again all right so our project is recompile let's see what this looks like new sample text still showing and now anything past my my initial hit is updating my comp account accordingly and within a couple seconds you'll notice things got recent sounds quite a few seconds and bam it's gone cool so this is kind of how you implement a comm system so our player character is counting our hits our UI is you know gently picking up that information pending on what happens and updating your comp count so what else can we do this when we had a couple of animations that make the presentation of a combo just a little bit more exciting so on a little bit of shake a little bit of wobble and a little bit of a fade out as we're counting down to the combo risa orders right now it's kinda it's kind of jarring right nothing happens we don't know what's going on oh there's our combo and you know within a few seconds it goes away so to do that what we need to do is look at you widget animation and you'll notice on your combo widget blueprint one of the things we have available to us is this animation section bottom left so if we have this animation or ever we add a new animation what this allows us to do is control the elements on the screen so let me go ahead and just spend a few minutes prepping this and I'll walk you through kind of what we have going on here all right folks so I got my my text box all cleaned up and now let's just go ahead and make sure that it's it's centered when we display this information I'll do it right a kind in the middle of our screen and then let's style this text box just a little bit so we use slightly slightly darker color let's give our font just a little bit more visible so maybe 48 it seems like a good size more or less and let's set our justification to be centered we can also add additional false but I don't really have any ones included right now so we'll leave that for another exercise and you have those for things like shadow offsets all right so a little bit of a shadow going on with your with your guy here you can mess around with you know the various shadow colors and things like that but I think we're good for now we'll leave this as this and I'll show you now what these animations on the problem up so I'm going to add a new animation called combo fade and what this animation is going to allow us to do is basically fade out this text over a period of time so our our reset is about five seconds so what I'm gonna do is I'm gonna make our text fade over five seconds as well so you'll notice here here's your timeline and for folks who have never worked with animation software they're all pretty much similar in the sense that you have tracks and a track represents sort of a layer of activity and on that track you can perform various operations and you can have a whole whole pile of these so in our case you'll notice if I'm just clicking on the canvas panel behind the track is picking up canvas panel as the input if I click on my text box it's picking up text box as my as my input or I thought perhaps we could drag it in but that's just for for the sequencer within the level editor so let's go ahead and select your text box track txt combo and there is the thing we're going to do an animation up now further to the individual tracks there's all the different sort of properties that then become available to you for your animation purposes so in our case we're just gonna look at color and opacity so we're gonna say is these are our default values so we have one you notice they represent our colors so one for the red two nine zero zero eight for blue and green and then our alpha is one so what we want to do is we want to add a keyframe at zero seconds before this animation starts and then at some point in time in the future so let's say we do it over five seconds we want to add another keyframe that's going to change our alpha from one to zero so now when we play our animation our text is going to gently fade out over those five seconds basically keeping in line with our timer of reset in the combos and there's some inaccuracies with this you can tie it you know together so everything operates off of one timer but for our purposes again we're not gonna we're not gonna do that but yeah there you go this remember this is how our alpha is going to fade and then we're gonna add a secondary animation and we're gonna call this combo shake and what this guy's going to do is serve an another track and we're gonna do this for our transform so we got our translation or rotation or scale etc and we're gonna add our first keyframe basically saying don't do anything and then maybe within let's say 0.1 of a second we're gonna add another keyframe but in this case we're gonna change the X to be fine and the Y to be 5 so it's gonna go to the right and down a bit so you can see how it kind of kind of wobbles and we can even add our rotation of maybe 15 that's maybe a little too aggressive let's do 5 so it's gonna go like this and then at Point 2 we're going to reset our angle to minus 5 we're gonna set our y2 5 and this negative 5 as well so it's gonna kind of do this little wobble thing and then another point one of a second later we're just gonna reset things back to what they were so now with every hit we should get this little wobble going just kind of showing that that combos are actually being you know executed and you can have some you know variants and random let's do this so it doesn't always pivot the same way but for our purposes we're just gonna stick with this okay so we have our two animations and now we need to reference them within our code so how do we go about doing that let's pop open our our class definitions and we're going to go to our widget class and we're gonna take a look at this guy here so let's create a couple of private member variables one of them is going to be actually both of them are going to be you widget animations our first one is going to be Pombal fade animation just cuz you want to be explicit with your variable name definitions and for the most part this would be cool if we could use the same sort of binding that we did with our new text block but we can't with animations in fact animation is a little bit of a pain in the ass to work with because we need to get all of the properties of the widget and then cast them accordingly to the widget animation I think there's a ticket around getting bind widget for for other components of the UMG elements but as far as I know it's so let's be good scientists and create a little reusable method that we can then reference for any other animation we choose to add so there's a couple of interesting little tutorials floating around the internet on how this is done I kind of took the the best of both worlds and basically we're going to do is at application or game start we're going to fill this map with all of the available widget animations for this widget and then by key or by name we can reference those animations at runtime for playback you know resetting etc but to do that we need a little method so we're gonna have this method called start it's going to return a widget animation and we're gonna say get Const and another little method that fills up this this map and this is why we have the native construct because when the switch gets created this guy's going to call our store widget animations method and then we can have access to them through here so let's go back to our combo widget let's say you start with your animations and what this guy's going to do is a little bit complicated in a way but but not too hard to understand so we're going to empty up the map just am you know safe site in case we call this method from other points in our timeline and then we're gonna do we're going to get all of the properties from the current passport and let's do a little checking if prop get class equals object you object you object property so you only care because there's other ones on our widget but we really don't don't care about those too much at least on this side you're gonna get our you object property and passed it from our pro okay and only get properties so we're gonna say if prop to do do do and you know what we actually let's not use the equals okay so there's our get class and we have our widget animation so now we can actually do a little bit of conversion on this so you wanna say you object because that's the base object definition I'm gonna say object prop yet object property value in container and the container is this so this should now give us our new widget animation object that we can do so there's an animation so if our wooden table nation is now available to us we can go ahead and and do some stuff so we're gonna say F name name widget animation movie scene and actually no it's because we're calling movie scene and perhaps that is not filled up yet if you recall you can have an animation all right so we got a new one without any track information so this is just an extra little null trying to ensure that now we have some information we can work with okay so there is our name and then we can say animations map atom name as our value and then widget animation or sorry annum name is our key and the widget animation as our value and the only other thing that we're going to do here oh sorry I thought already the definition on this so sorry this all this code is actually going to be a while loop because there is more than one property so while our property is still available to us we're gonna do this work I say prop equals prop next so basically we're iterating over all the various properties and ensuring that we okay so this will give us all of the widget animations now we can go ahead and create a little helper method that's gonna bring back a a specific animation [Applause] [Applause] all right and if our widget animation is kosher we turn our widget animation otherwise return a null pointer animation by name Oh make it a constant okay so there's our animations there is the map and now we actually want to play these guys back as things are being updated so what we're gonna do is we're gonna say if cobble fade animation then you say play animation which is a built-in method you know it takes in our animation so comma fade animation our start time is gonna be zero so right at the beginning we're gonna loop this once our play mode is going to be forward and there's different ones those you might have noticed ping pong and a couple of other ones backwards and our playback speed is going to be 1f so just forwards at a constant rate and then we can do the exact same thing with our combo chicken animation shake animation alright and finally in our native constructor which is again similar to begin play we want to call store widget animations so when our widgets we say [Applause] all right there just double check make sure everything is in place and let's recompile this looks like alright guys so we're all recompiled let's take a look what this looks like that steers our text block right in the center yeah we hit our shaking is not working and it's not working because your class oh sorry it's supposed to be property class not get lost the other thing I also added in was just a little message after a second recompile and to do that you need engine page I just wanted to print out the actual animation names that were being rendered as this which was being accentuated so let's recap I'll just give it one more shot all right let's see what this looks like now so we should see is in the top left hand corner just a few messages showing the oh there we go combo shake and combo fade being loaded and you know let's get rid of the default text block so it just looks a little bit prettier okay so there was our animations we just loaded them from our widget there there we go as we punch you'll notice our little combo counts up and shakes a little bit and as I step away it just fades out gently into nothingness cool and then if I were to you know kick around again boom or combos a reset if I catch it just sort of as it's beginning to fade I still have a little bit of time to resume my combo so you see it kind of comes back although more timers are being actually recess we generally have a little basis of of a comme des mechanic you can now start using these values to multiplier hit points critical hits and all kinds of interesting you could even now you know have different animations and colors and you know changes to the UI widgets as these things occur so as you guys can see it wasn't too bad to generate these combos and I hope you tune in next time when we start looking at expanding our game to include you know health and sprinting and crouching and various with other movements for our character to interact with in the world so thank you for tuning in and hope to see you guys next time [Music]
Info
Channel: Jolly Monster Studio
Views: 14,721
Rating: undefined out of 5
Keywords: unreal, engine, c++, ahud, hud, uuserwidget, uwidgetanimation, widget, animation, tutorial, example, ue4
Id: lYfXkxlInVI
Channel Id: undefined
Length: 59min 6sec (3546 seconds)
Published: Tue Mar 12 2019
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.