Hi, welcome back for the next tutorial. And in this tutorial, I'll be explaining how to create a basic Command UI for top down turn based games using HUD blueprints. By the time we reach the end of the tutorial, we'll have a Command UI with movement and fire action commands, and a player character that responds to the commands. Here's a screenshot showing the end product:
Oh, and this tutorial is gonna be quite big, compared to earlier ones. So I advise everyone to go through the screenshots, before reading through. If it's clear, there's no need to read through the whole thing, partly because I've written this with a beginner audience target in mind. Ofcourse, if you have doubts, I hope they will be clarified in the written description. If not, feel free to ask me in the comments.
So let's get started. Again, I'll be starting with the top down template. First of all, we need to create a new HUD blueprint. If you're a beginner, you can find this by first right clicking on the content browser, then selecting 'Blueprint' and search for 'Hud' under 'All Classes'. Click on HUD and select it. So now that we have one, we need to set it as the default HUD class for your game. For that, we need to go to 'MyGame' blueprint and set your new blueprint under the 'HUD Class' in the defaults tab.
Now let's get back to the HUD blueprint. First, we need to create a function for drawing the buttons for our UI. Let's call it 'Draw Button'. So basically, creating a button involves 3 parts: first we need to set it's texture; second we need to set the font (if you need to specify the button name); third and last, we need to set the hit space which would trigger the button functionality. For this function, we need 4 inputs:
1) Button Screen Location (Vector 2D)
2) Button Text (String)
3) Hit Box Name (Name) - [Helps us identify the clicked button by name, later on]
4) Button Texture (Texture 2D)
From now on, it'll be easier if we have a screenshot alongside as well. So her's one shot of the function body:
Before diving in, there's one thing you should know. In this case, when we specify the button coordinates, Unreal actually takes the center point of the button into consideration. Whereas for the button textures, it actually means the top left corner of the texture. As a result, we need to get the button dimensions, divide it by two, and then subtract from the button location (center), in order to give the location for the button texture. Similar considerations have to be taken into account for the font as well.
So now, if you notice the screenshot, you can see that I've done the above mentioned calculations, before drawing the texture and font. I've hard-coded the button dimensions to (x,y) = (256,128), as seen in the the input for the hit box node. As you see, we first use the 'Draw Texture Sample' to well, yea draw the button texture. Based on the calculations, we specify the location of the texture relative to the button location (Button Screen Location input). We then assign the Button Texture as input to the node as well. Next, we move on to the font, and we use a 'Draw Text' for that. Inputs include the actual text data (Button Text input), text color, screen location and the font. Before setting the font, we use the font type and text to calculate the location of text relative to the button center. Finally, we add a Hit Box to specify the button hit space. As mentioned earlier, the hard-coded button dimensions are set as the input. So with that, we have the 'Draw Button' function ready.
Now let's move back to the Event Graph of out HUD Blueprint. First let's create a bool variable that let's know when we need to display the HUD. I'm gonna name mine as 'DisplayHUD'. Then we use the Receive Draw Hud event to draw the buttons. We check if the 'DisplayHUD' is set to true. If it is' we call the 'Draw Button' function twice; one for the move command and one for the fire command. Here, we specify the function inputs including button screen locations, button text, hit box name and button texture. Again here's a screenshot to avoid any confusion:
We need a custom event to call our hud functionality from the player controller, based on player input. Everytime the player right clicks on the navigable space, this event will be called in to display the hud. So let's create one, as shown in the previous screenshot, with 3 inputs:
1) Hit Location (Vector) - For storing the clicked location in the level
2) Actor Location (Vector) - Player Location
3) Forward Vector (Vector) - Player character's forward vector, for getting the firing direction and projectile spawn location.
We store all these values into local variables inside the hud blueprint, whenever the event is called. Alongside, we set the 'DisplayHUD' variable to True.
Next, we need to call this event from the player controller. So let's go to the event graph of MyController blueprint. This is what it's gonna look like, by the time we're finished with our controller:
As you can see, I'm using right mouse button click to get the player input. Every time the player right clicks on the level, I get the hit result under cursor by channel, break the hit result in order to get the hit location. This data, along with player character location and forward vector and used to call our custom event from hud blueprint: Event Toggle HUD. Now all we're left to deal with are the workings of the fire and movement commands. For implementing that, we head back to the HUD blueprint once again.
We're gonna use the Receive Hit Box Click event to see which button the player clicked. And this is the reason why we used the Hit Box name earlier while making our button function. We add a switch node with custom pin names equivalent to our button hit box names. No matter which button the player clicked, we will first set 'DisplayHUD' to false. If the player clicked on the move command, it's pretty easy to handle it. We just get our controller and use the 'Simple move to location' node with the hit location we received earlier as the input. Handling the fire action command is a different story. It would make sense to have a screenshot over here first:
Before we spawn the projectile for firing, we're gonna rotate the player to face the direction of the hit location. In order to achieve this, we first get the forward vector, multiple it by say 100, and add it to the actor location. We then use this data along with the hit location and find look at rotation to get the necessary yaw value of the new rotation value. We then get the actor rotation and change it's yaw value to this new yaw value. We then set actor rotation using this new yaw value. I'm using a delay of .2 seconds after this, so that the player has finished turning to face the new direction before firing the projectile. Then I go to MyController and create a new function - 'Fire at Hit Location', with the three vector inputs shown above. I then call this function after the above mentioned delay. As you may have noticed, I'm getting the forward vector again, since the player character is now facing a different direction. Now here's a screenshot of the function:
I'm not going into the details of it's implementation, as I have already explained the process in one of my earlier tutorials. You can find it here:
With that, we have implemented a working HUD based Command UI for the Top Down template. Just to make it a bit more realistic, you could add the logic from the screenshot below, to your projectile blueprint, the making of which is explained in the above link.
This code, makes sure that your projectile is destroyed after impact with other actors. I've also added a particle system to be spawned at impact.
Alright, that's all for this weekend. See you at the next post.