Introduction

My previous post Custom UserWidget control for UMG, UE4 treated about creating custom UserWidget with a TextButton as an example. Styling should be next big step in creating a universal control component for UMG. In this article I will show you how to accurately control this UserWidget’s states visual feedback.

What will you gain?

Here are several pros that you get using proposed approach.

Unified layout style

Creating a custom control with customized style allows for fast layout building which is consistent with the rest of the application.

More polished control (potentially)

Taking care of style in a single custom control motivates to make it more polished as you are doing it only once.

Flexibility

Having controls using the same style helps to modify it later. A simple change in the control’s UserWidget modifies the look of control in the whole application! The same thing concerns repairing a bug when project is in advanced state.

Discovery of fantastic (and free) assets pack

This solution uses a monolytic #GameUI Essentials assets pack. It was released initially for free and hopefully it still is as you are reading this article.

Prerequisities

Skill

A basic knowledge about UE4 and UMG would be desirable. C++ code will be used but one should make it through using information inside this article.

Software

Unreal Engine

This tutorial was created in UnrealEngine 4.12.5. You can obtain UE4 from official website.

Microsoft Visual Studio

We will use the code very sparingly but it is a must in this solution so you need to obtain free Visual Studio 2015 Community Edition from here.

Operating System

You will need a Windows 7 or higher (this solution uses Windows 10).

Example project

This solution is based on project from previous article Custom UserWidget control for UMG, UE4 and it can be dowloaded from here. You will need to run the TextButtonTest.uproject file and later compile the code to prepare the game to be run.

The complete project from this article can be downloaded from here.

Hardware

Any PC capable of running UE4 will be suitable.

Configuration

Downloading base project

This solution is based on project from previous article Custom UserWidget control for UMG, UE4. Please download if from here and extract the archive. Project structure should look like this:

downloading.PNG

Now run the TextButtonTest.uproject and click OK if it asks to recompile the project. Finally it should open a default untitled map. Open SimpleMap from the Content Browser and we are good to go.

loaded_map.PNG

Open the BP_TextButtonWidget Blueprint. This is the UserWidget control that we will style in the following sections.

textbutton_nostyle.PNG

Getting required assets

To style our TextButton UserWidget control we need to style the Button and the Text and later react on their state changes so they respond accordingly. Explicitly we need following assets:

Button

Background for Normal, Hovered and Pressed state. We will use the gameui-menus_v1-1 assets pack from monolytic #GameUI Essentials.

Text

A suitable font. We will use the Montserrat font, so we are consistent with the assets pack for Button.

Downloading monolytic #GameUI Essentials assets pack

We will use the monolytic #GameUI Essentials assets pack (you can showcase them on the official website). Open the first link and click I want this! button.

iwantthis.PNG

On the next screen input your email and click Get.

get.PNG

This should forward you to the order receipt, where you need to click View product button.

viewproduct.PNG

Finally, you’ll access the download page. Please download the gameui-menus_v1-1 assets pack.

downloadmenus.PNG

Extract the downloaded archive somewhere where you’ll have an easy access to. I do not advise putting them in the project folder. We will put there only the assets that we use.

Finally you should end up with folder consisting of following folders and files:

extracted_menu.PNG

Downloading Montserrat font

The Montserrat font can be downloaded from here. Open the link and click Download OTF.

downloadfont.PNG

Extract the archive in a suitable location, but not in the Unreal Engine project itself. You should get the following files:

extrctedfont.PNG

Creating UE4 assets

Getting raw images and fonts is only a first step of creating a style for our TextButton. The next thing it to make a UE4 assets out of them, so we can use them in the UserWidget.

Target layout

The effect that we want to achieve is showcased on the 01_mainMenu_1.jpg image. If you open it you can see how we would like it to look at the end of article.

targetbuttons.PNG

TextButton in normal state should have black background and white text.

TextButton in hovered and clicked state should have white background and black text.

Creating TextButton background assets

Open the yourlocation\gameui-menus_v1-1\01_mainMenu_1_assets folder. Image shown in 01_mainMenu_1.jpg was chopped to usable slices. We need the menu_1_clear.png and the menu_2_clear.png.

menuchoppedslices.PNG

Select those files and drag them to the Unreal Editor’s Content folder. Unreal Engine will automatically convert them to usable assets.

draggedbackgrounds.PNG

Now rename the menu_1_clear asset to textbutton_background_white and menu_2_clear to textbutton_background_black. Click Save afterwards.

nameschangedforbackgrounds.PNG

Creating TextButton font asset

This will be a little more tricky than the background assets. Click RMB (Right Mouse Button) in the Content folder and select User Interface -> Font.

pickingfont.png

Rename the asset to Montserrat and open it.

We need to add a Regular Font to the Font Family (types of font – Regular, Bold, Italic, etc). Click Add Font button, rename it to Regular and click the Folder icon. Next, navigate to the montserrat folder and select Montserrat-Regular.otf.

selectingregularfont.PNG

This is the only font that we need for our TextButton. You can enhance the Composite Font to support bigger Font Family. Save changes and close the window.

Altering the style of TextButton

Now we have all required assets to alter the style of TextButton. Let’s start with the Button.

Altering style of Button Widget

Open BP_TextButtonWidget and select the Button from Hierarchy window. In the Details panel open the Appearence -> Style menu. You can find there the Normal, Hovered, Pressed and Disabled states.

buttonstyles.PNG

We will omit the Disabled state and focus on the other 3.

Expand the Normal menu and select an textbutton_background_black in the Image field. The Button preview will change accordingly.

changing_normalstate_image.PNG

Now repeat the process with Hovered and Pressed states, but using the textbutton_background_white asset and save changes.

alteredcolors.PNG

Test run the game

Let’s test run the game now.

firstrunblack.PNG

As we can see,  changing Button’s background colors already altered it’s usage in UserWidget using the TextButton control. When the Button is not bothered it displays the Normal state.

Let’s Hover on the Button.

hoveringnotext.png

Button responded accordingly changing it’s background to white asset. The problem is that we can’t see Text now, because it’s color is always set to white.

For completion let’s click the Button.

clickingnotext.png

Button responded accordingly setting the background to white asset. We also got the TextButton Clicked! text printed on the screen.

Let us take care of the TextButton’s Text Widget now.

Altering style of Text Widget

In our Text Widget we would like to change the color and the font of printed text. Color must be changed dynamically based on the Button’s state.

Changing Text Font

Changing font is easy, as it will not change on Button’s state.

Open the BP_TextButtonWidget’s Designer and select Text in Hierarchy window. In the Details panel find the Appearance -> Font field and change it from default Roboto to our Montserrat asset.

changingfont.png

Text’s font on the preview will change accordingly.

Changing Text Color

Changing Text color needs additional logic because we need to react on the Button’s state so Text color is always in contrast to it.

Creating Blueprint logic

Switch to Graph and add 2 variables:

  • TextButtonHoveredTextColor and
  • TextButtonUnhoveredTextColor.

Both of them need to be of Type Slate Color. Compile Blueprint and set the Default Values for new variables: black for Hovered and white for Unhovered.

buttonhoveredcolor.PNG

Let us also create 2 corresponding functions:

  • ChangeTextColorOnButtonHover and
  • ChangeTextColorOnButtonUnhover.

Open ChangeTextColorOnButtonHover, drag TextBlock_0 and pick get. Do the same for TextButtonHoveredTextColor. Next, drag a connection form TextBlock_0 and pick a Set Color and Opacity node. Connect ChangeTextColorOnButtonHover to new node’s In Color and Opacity field and drag Exec from the function input to that node.

onhoverfuntion.PNG

Repeat the process with ChangeTextColorOnButtonUnhover function, but use the TextButtonUnhoveredTextColor variable.

Now go to the Designer, select Button and create the OnHovered and OnUnhovered nodes.

events.PNG

Go to the EventGraph and add an execution connection from OnHovered node to ChangeTextColorOnButtonHover function and from OnUnhovered node to ChangeTextColorOnButtonUnhover function.

connectedtohovers.PNG

Test run

Let’s test run the game.

testrun2.PNG

At first glance we can see that the font has changed. Also text color in contrast to the button’s background as it should. Let’s try to hover over it.

testrun2hover.PNG

Everything looks as we planned. Button’s state changed to Hover and so is the Button’s background. Our logic reacted on the OnHovered event and changed the color of text to black.

Let’s click it.

testrun2click.png

Responded as we wanted. Button and Text Widget’s are still in contrast.

Let’s leave the Button.

testrun2unhover.PNG

Our logic responded to the Unhovered event and changed the Text color back to white.

So are we finished? Unfortunately not. Let’s click the Button and drag the clicked cursor outside the Button.

testrun2clickedunhover.PNG

Our logic is broken! We unhovered the Button so the Text changed it’s color to white, but Button is now in the Clicked state as we didn’t stop pressing LMB (Left Mouse Button).

We need to address this problem.

Altering Blueprint logic to address the Unhovered Pressed Button problem

To resolve this issue we need to respond to another 2 events of a ButtonOnPressed and OnReleased. Go to BP_TextButtonWidget, select Button from Hierarchy window and add both mentioned events.

moreevents.PNG

Now we need to add a boolean variable named IsButtonPressed that has default value of false.

isbuttonpressed.PNG

On the EventGraph connect the OnPressed event to setting the IsButtonPressed value to true and the OnReleased event to setting the IsButtonPressed value to false.

settingpressedandreleased.PNG

Last thing is to alter the ChangeTextColorOnButtonUnhover funtion so it will know when to change the Text color according to the IsButtonPressed value.

After the ChangeTextColorOnButtonUnhover input place a Branch node with an input being the IsButtonPressed variable. Disconnect the True exec connection if it is connected and connect the False to Set Color and Opacity node.

alteredunhoverfuntion.PNG

That should do it! Let’s test it out.

Test run

Click the Button and drag it the mouse out of it without letting go the LMB.

repaireddrag.png

Looks good, now release the LMB.

repaireddragreleased.PNG

Everything works! This concludes the styling process.

Note!
How is it possible that Text changed the color from black to white
after releasing button in the unHovered state? It should be left in 
the black state because we omitted the changing color on the onUnhovered 
event. Well it turns out that after releasing the Button 
in the unHovered state, UE4 calls unHovered event once again! 

This way our ChangeTextColorOnButtonUnhover function is called
twice but changes the color only when we know that the IsButtonPressed is false.
I don't know if this feature is not a bug, so this solution may need to be
altered once Epic changes this behavior.

Conclusion

Styling a UserWidget control requires to take care of various Widget’s states so the UserWidget works and looks consistently. A good thing  is that it only needs to be done once, which helps to couple the integration problems to simple solutions in opposition to Blueprint Spaghetti when taking care of every Widget’s problem in a single UserWidget.

What’s next?

Designing a responsive screen based on UserWidget

If having custom UserWidget controls helps to build another UserWidget, then it’s time to address the problem of creating such a UserWidget screen. I will show you how to recreate the Main Menu from the #GameUI Essentials assets pack.

01_mainMenu_1.jpg

Creating a Screen Management System

The more screens to be managed the bigger the problem with coping with the logic. I will show you how to address this problem, where a single HUD takes care about managing screens being UserWidgets without them knowing anything about each others existence.

Advertisements