Building the User Interface


In Part 2 - Reading the Match Logs I outlined the first steps to reading the match logs for the visualizer.

This time around, I'll dive into some details of setting up the Unreal Project, initial UI and adding C++ classes to the project.

Step 1: The Unreal project

For this project there wasn't much setup required in terms of project settings. Using Unreal Engine 4.21.2, I used the Empty project template under the Blueprint section (as most of the visualizer work will live in Blueprints).

I also opted to NOT include any of the Starter Content provided by the engine.


That's it for project setup, for now.

The first component I needed to to build, was some UI to allow the user to select the directory containing the match logs for the specific match they would like to run through the visualizer.

I started, as usual, by adding a few folders to the content browser in the engine. This is simply to help organise all the different components into folders I would likely use, and these will probably change as I go along. I added four folders to start with:

1: Blueprints - For collecting any blueprint classes that are responsible for general operations

2: UI - For all the UMG UI Designer widget blueprints

3: Fonts - To keep any Font files and assets

4: Movies - To keep any video source files and assets

The content browser window now looks like this:


UMG: The First Widget

For the splash screen, where the user will pick the match directory, I created a new UMG Widget blueprint named WBP_SPLASH_MENU.
The prefixes I use are just to help me keep track of everything, (WBP_ for Widget BluePrints, for example) and are not necessary at all.

After creating the widget, I put together a few elements in the design view, including the Entelect Challenge promo video and logo.


Playing the Promo Video

To get the promo video to actually play, there was some work to do. Back in the content browser, in the media folder, I imported the source video.

From here, I had to create a Media Player object and an associated Media Texture object. Editing the Media Player object to select the imported video, will automatically update the media texture object, to play the video file as a texture.

Using this media texture, I created a material, which I can apply to an object or canvas in the project. This material is pretty basic, and just maps the media texture to the material that will be applied to an object / canvas. The material blueprint looks like this:


The material domain controls how the material is rendered. For this type of UI I used the User Interface domain.

This material is then applied to the Image element in the widget designer, to map the media texture to the 'image'. For a detailed breakdown on playing video in UMG please see the Unreal Documentation here.

With the media texture setup, and the splash screen layout complete, there was still a bit of work to be done.
Switching from the designer view to the event graph, I had to let the widget know when to start playing the video, as well as pausing the video once the match folder select dialog is opened.

The event graph for this portion of the behaviour looks like this:


The Event Construct node is a built in event that triggers when the widget is added to the screen, and the On Clicked event is a standard event on button components.

The media player node is a simple variable added to the widget, which acts as the target for the Open Source node. The media source in the Open Source node is the original source file that was imported to the content browser. The media texture in the designer updates as the source plays, so I needed to trigger the source to start playback.

When the user clicks the Select Match button, I set the On Click binding to pause the video and call the Get Match Root Directory function that opens the file select dialog.

Time for some C++

The Get Match Root Directory node is a custom node built in C++ as part of a Blueprint callable utility library I built for this project.

To add C++ classes to an Unreal project is fairly simple. Right click anywhere in the content browser and select New C++ Class.

This brings up a new dialog that lets you select the parent class for the new C++ class. In this instance I ticked the Show all Classes box and selected BlueprintFunctionLibrary as a parent class.


Opening the project in XCode (See Footnotes) now had the new class definition, that looked like this:

#pragma once 

#include "CoreMinimal.h"
#include "Kismet/BlueprintFunctionLibrary.h" 
#include "EC2019Utilities.generated.h" 

UCLASS() class EC2019_API UEC2019Utilities : public UBlueprintFunctionLibrary 

Some things to note is that #include "EC2019Utilities.generated.h" has to always be the last include in any file. This will be important later.

Also, your class will include the GENERATED_BODY() macro, which is required by the engine. This macro is used primarily to generate the class registrations code and to map your class for the engine's reflection system. More details can be found in the Unreal Engine documentation.

In closing

In the next post, I will be getting into the file handling functions in the Blueprint function library and how everything is put together.

There will be some temporary 'workarounds' in place and the C++ may be a little messy, since I'm an iOS dev by trade, so fair warning.

If you have any comments, questions or suggestions, please drop a comment on this post, or send a message from the Contact page.

While Unreal Engine 4.21 does support using Jetbrain's CLion for the C++ portions of the project, I had some trouble getting the code completion and include directories working properly.

Be careful of doing a Clean Build in XCode. It seems to delete some files from the engine itself, which will then require you to use the Verify option in the launcher to repair the engine.

Copyright Notice

The Entelect Challenge 2019 logo and the Entelect Challenge Promotional Video that I use in the visualizer belong to Entelect Software.