You are on page 1of 671

Title Page

Unreal Engine Blueprints Visual Scripting Projects

Learn Blueprints Visual Scripting in UE4 by building three captivating 3D Games

1
Title Page
Lauren S. Ferro

BIRMINGHAM - MUMBAI

2
Copyright and Credits

3
Unreal Engine Blueprints Visual Scripting Projects
Unreal Engine Blueprints Visual Scripting Projects
Copyright © 2019 Packt Publishing
All rights reserved. No part of this book may be reproduced, stored in a retrieval system, or transmitted in any form or by any means, without the prior written permission of the
publisher, except in the case of brief quotations embedded in critical articles or reviews.
Every effort has been made in the preparation of this book to ensure the accuracy of the information presented. However, the information contained in this book is sold without
warranty, either express or implied. Neither the author, nor Packt Publishing or its dealers and distributors, will be held liable for any damages caused or alleged to have been caused
directly or indirectly by this book.
Packt Publishing has endeavored to provide trademark information about all of the companies and products mentioned in this book by the appropriate use of capitals. However, Packt
Publishing cannot guarantee the accuracy of this information.

Commissioning Editor: Amarabha Banerjee


Acquisition Editor: Larissa Pinto
Content Development Editor: Francis Carneiro
Technical Editor: Ralph Rosario
Copy Editor: Safis Editing
Project Coordinator: Pragati Shukla
Proofreader: Safis Editing
Indexer: Rekha Nair
Graphics: Alishon Mendonsa
Production Coordinator: Deepika Naik
First published: February 2019
Production reference: 2280219
Published by Packt Publishing Ltd.
Livery Place
35 Livery Street
Birmingham
B3 2PB, UK.
ISBN 978-1-78953-242-5
www.packtpub.com

4
Contributors

5
About the author
About the author
Lauren S. Ferro has a Ph.D. in player profiling and modeling. She is currently an
Adjunct Professor and researcher at Sapienza University, in Rome. Lauren is also the co-
organizer of the Unreal Engine Meetup in Rome. In addition, she created the game design
resource, Gamicards, which is a prototyping tool for game experiences. At heart, she is
intrigued by how we interact with the world and those in it.
Packt Publishing – For the opportunity to write this book and be a part of the authoring
community. A special thanks to Larissa and Francis for their patience and support
throughout the development of this book.
Francesco Sapio - for your help, support, patience, and guidance, and for being you.
The reviewers - for your time, comments and suggestions, which have all made this book
what it has become.
My family - for their motivation, patience, support, and encouragement not just during
the development of this book but for everything.
You, the reader - I hope that this book takes you on marvelous and intrepid adventures.

6
About the reviewers
About the reviewers
Ahmad Iftikhar, 31, is the Director of a cutting-edge design company, Creative Bugs
Pvt. Ltd.
A graduate with majors in Game Design from the University of South Asia, he is a
veteran designer with over 11 years of experience. He has mastered innumerable tools
including 3DS Max, Unity 3D, Unreal Engine, Cry Engine & Torque.
Ahmad has worked for renowned organizations such as iWin, Digital Chocolate,
Chrysler, Game View Studios. Moreover, he has rendered his expertise for US National
Guards. He has a plethora of projects to his credit including Torque 3D Game
Development Cookbook, Coconut Queen & numerous other 3D games.
I would like to thank my family & my mentor (Muhammad Junaid Malik) for all the
support they gave me throughout the years.
Agne Skripkaite is a UE4 software engineer with a particular interest in VR applications.
Agne has a BSc physics degree with honors from the University of Edinburgh and
became a full-time engineer partway through a physics PhD program at Caltech. Over the
last few years, Agne has developed for room-scale and seated VR games as part of teams
of various sizes, from two-engineer teams to large development teams. Agne has also
served as a user comfort and motion sickness mitigation expert for seated VR
applications.

7
Packt is searching for authors like you
Packt is searching for authors like you
If you're interested in becoming an author for Packt, please visit authors.packtpub.com
and apply today. We have worked with thousands of developers and tech professionals,
just like you, to help them share their insight with the global tech community. You can
make a general application, apply for a specific hot topic that we are recruiting an author
for, or submit your own idea.

8
About Packt

mapt.io
Mapt is an online digital library that gives you full access to over 5,000 books and videos,
as well as industry leading tools to help you plan your personal development and advance
your career. For more information, please visit our website.

9
Why subscribe?
Why subscribe?
Spend less time learning and more time coding with practical eBooks and Videos
from over 4,000 industry professionals
Improve your learning with Skill Plans built especially for you
Get a free eBook or video every month
Mapt is fully searchable
Copy and paste, print, and bookmark content

10
Packt.com
Packt.com
Did you know that Packt offers eBook versions of every book published, with PDF and
ePub files available? You can upgrade to the eBook version at www.packt.com and as a
print book customer, you are entitled to a discount on the eBook copy. Get in touch with
us at customercare@packtpub.com for more details.
At www.packt.com, you can also read a collection of free technical articles, sign up for a
range of free newsletters, and receive exclusive discounts and offers on Packt books and
eBooks.

11
Preface
Preface
Have you ever had an idea for a video game or interactive experience but lacked the
programming or technical skills? Then this book is for you. The Blueprint Visual Scripting
language helps you to create gameplay elements from within Unreal. This book will
provide you with the essential foundation to learn the essentials so that you can build
various simple to complex interactive experiences quickly and easily without writing any
code.

The book starts off with the basics – what is Blueprint, how to create basic blueprints,
and how to set up the fundamental components of a game. As you progress through the
chapters, you will gradually move on to build your first minimalistic 3D platformer game
that has its own quest system. Next, you will create a survival maze game and learn all
about adding additional features to the game, such as audio, special effects, and AI, using
Blueprints. Finally, the third and final project will explain how to build a multiplayer
game that will allow you to play with other people on a network. By the end of this book,
you will have completed three awesome projects and will be equipped with the
knowledge and skills required to create complex games with AI, amazing interfaces,
immersive environments, and exciting multiplayer experiences.

12
Who this book is for
Who this book is for
This book doesn't assume any prior knowledge. Even if you don't have Unreal installed
and you are new to game development or you're just starting out with Unreal Engine 4's
Blueprint Visual Scripting system, this book is for you.

13
What this book covers
What this book covers
Chapter 1, Getting Unreal, will set the scene for the rest of the book. Here, the reader
will learn about the essential parts of the Unreal Engine. They will also create the first
level, add a basic game object, apply a material to it, all in preparation for the rest of the
chapters within the book.
Chapter 2, Understanding the Basics of Blueprints, will build upon the previous chapter.
Here, the reader will begin to learn and consolidate their knowledge of Blueprints. They
will add basic movement to their game object, create a collision mechanism, and create
triggers.
Chapter 3, Improving Interaction, will explain interfaces for objects and how to create
them to extend the player interaction. In addition, the chapter will also cover creating
Blueprint functions, when they are appropriate to use, and how to make them easy to be
read by others, as well as how to create modular and reusable Blueprints. Lastly, the
chapter also covers creating rerouting nodes.
Chapter 4, Adding UI Elements, will cover the basics of what UIs/HUDs/GUIs are and
their importance in game design. It will also cover how to implement UI/HUD/GUI
elements within the UE4 project. Lastly, readers will learn how to connect those elements
to gameplay (for example, making the health bar diminish if the player collides with an
object).
Chapter 5, Adding an Inventory, extends upon the previous chapter. The readers will
learn how to create an inventory system that will allow the player to collect and use items
that they find. They will learn how to create Blueprint scripts that will allow players to
pick up and collect items (health, weapons and ammo, and magic). Next, the reader will
learn how to add these collected items to the inventory and how the player can then
access and use items.
Chapter 6, Creating an Adventure, will explain basic level design and how to create a
game environment. In addition, the reader will learn how to create a basic quest system.
Lastly, the reader will learn how to receive and give damage to objects.
Chapter 7, Reducing Loneliness with AI, will introduce how AI works in Unreal and how
AI controllers work. Then, the reader will be guided through creating a simple AI, which
will be extended in the next chapter.

14
What this book covers
Chapter 8, Upgrading the Gameplay, will explain how to create in-game scenarios where
AI enemies are destructible. In addition, this chapter will cover how to create a respawn
system for the player, enemies, and items. Next, this chapter will define gameplay
conditions to determine whether the player wins or loses. Lastly, this chapter explains
how to create game states for when the player wins or loses (for example, from dying).
Chapter 9, Upgrading the AI, dives deeper in the topic of AI so the user will know how
to unlock the full power of Behavior Trees to their advantage to create dynamic enemy
AI for their games.
Chapter 10, Adding Audio, will teach the reader how to add audio effects to various parts
of the game environment. It will give the reader an overview of the audio system in
UE4,and how to create ambient sounds.
Chapter 11, Making It Pretty, will explain how to add a range of different effects using
Blueprints, basic dynamic materials, particle effects, and how to trigger them within
Blueprints.
Chapter 12, Game Analytics, Debugging, and Functional Testing, will cover the
importance of player analytics and how to balance your game, as well as how to use the
Session Frontend in development. Moreover, this chapter will illustrate the different
debugging and automated tests functionalities built into Blueprints in order to make faster
iterations with less margin for error.
Chapter 13, Level Streaming and World Composition, will explain how to use level
streaming to create a world/indoor/combat map system and keeping things running
smoothly along with the game loop.
Chapter 14, Animating the Hound, will begin the third and final project for this book.
More specifically, we will look at animation blueprints by learning how to animate a
hound. In addition, we will also explore the foundations of multiplayer games.
Chapter 15, Data-Driven Gameplay, will explain the importance of data tables to drive
gameplay, and how to effectively integrate them with Blueprint. This will provide
designers with much better iteration time, and the process is automated with Blueprint.
Chapter 16, Foundations of Multiplayer, will explain how to create a simple local
multiplayer setup, a (multiplayer) player spawning system, and shared cameras. This will
extend upon what we have already covered but with its users being within a multiplayer
15
What this book covers
environment.
Chapter 17, Extending the Multiplayer Setup, will extend upon the multiplayer setup in
the previous chapters. The reader will learn how to create the “lobby” menu system so
that players can create and join the game and interact in the game. In addition, they will
also learn how to test and ensure that everything is running smoothly.
Chapter 18, Adding Additional Features, will explain how to replicate events and
variables properly so that information will travel between the players.
Chapter 19, Building and Publishing, will explain that although packaging the game
might seem as easy as pressing a button, it actually isn't. Especially in an engine such as
Unreal, packaging is a crucial step, and the many options need to be understood well
before exporting the package.

16
To get the most out of this book
To get the most out of this book
No prior game design experience is required. However, basic knowledge of Unreal
Engine would be useful.

17
Download the example code files
Download the example code files
You can download the example code files for this book from your account at
www.packt.com. If you purchased this book elsewhere, you can visit
www.packt.com/support and register to have the files emailed directly to you.
You can download the code files by following these steps:
1. Log in or register at www.packt.com.
2. Select the SUPPORT tab.
3. Click on Code Downloads & Errata.
4. Enter the name of the book in the Search box and follow the onscreen instructions.

Once the file is downloaded, please make sure that you unzip or extract the folder using
the latest version of:
WinRAR/7-Zip for Windows
Zipeg/iZip/UnRarX for Mac
7-Zip/PeaZip for Linux

The code bundle for the book is also hosted on GitHub


at https://github.com/PacktPublishing/Unreal-Engine-Blueprints-Visual-Scripting-
Projects. In case there's an update to the code, it will be updated on the existing GitHub
repository.
We also have other code bundles from our rich catalog of books and videos available
at https://github.com/PacktPublishing/. Check them out!

18
Download the color images
Download the color images
We also provide a PDF file that has color images of the screenshots/diagrams used in this
book. You can download it here:
https://www.packtpub.com/sites/default/files/downloads/9781789532425_ColorImages.pdf.

19
Conventions used
Conventions used
There are a number of text conventions used throughout this book.
CodeInText: Indicates code words in text, database table names, folder names,
filenames, file extensions, pathnames, dummy URLs, user input, and Twitter handles.
Here is an example: "Mount the downloaded WebStorm-10*.dmg disk image file as
another disk in your system."
A block of code is set as follows:
html, body, #map {
height: 100%;
margin: 0;
padding: 0
}
When we wish to draw your attention to a particular part of a code block, the relevant
lines or items are set in bold:
[default]
exten => s,1,Dial(Zap/1|30)
exten => s,2,Voicemail(u100)
exten => s,102,Voicemail(b100)
exten => i,1,Voicemail(s0)
Any command-line input or output is written as follows:
$ mkdir css
$ cd css
Bold: Indicates a new term, an important word, or words that you see onscreen. For
example, words in menus or dialog boxes appear in the text like this. Here is an example:
"Select System info from the Administration panel."
Warnings or important notes appear like this.
Tips and tricks appear like this.

20
Get in touch
Get in touch
Feedback from our readers is always welcome.
General feedback: If you have questions about any aspect of this book, mention the
book title in the subject of your message and email us at
customercare@packtpub.com.
Errata: Although we have taken every care to ensure the accuracy of our content,
mistakes do happen. If you have found a mistake in this book, we would be grateful if
you would report this to us. Please visit www.packt.com/submit-errata, selecting your
book, clicking on the Errata Submission Form link, and entering the details.
Piracy: If you come across any illegal copies of our works in any form on the Internet,
we would be grateful if you would provide us with the location address or website name.
Please contact us at copyright@packt.com with a link to the material.
If you are interested in becoming an author: If there is a topic that you have expertise
in and you are interested in either writing or contributing to a book, please visit
authors.packtpub.com.

21
Reviews
Reviews
Please leave a review. Once you have read and used this book, why not leave a review
on the site that you purchased it from? Potential readers can then see and use your
unbiased opinion to make purchase decisions, we at Packt can understand what you think
about our products, and our authors can see your feedback on their book. Thank you!
For more information about Packt, please visit packt.com.

22
Section 1: Foundation
Section 1: Foundation
In this section, you'll will learn about the basic setup of the Unreal Engine, Blueprints,
and basic but fundamental game components, such as the HUD/UI, AI, and so on. We
will also be making a minimalistic 3D platformer, in which we'll create basic movement
using Blueprints, along with a simple quest system.
In this section, we will include the following chapters:
Chapter 1, Getting Unreal
Chapter 2, Understanding the Basics of Blueprints
Chapter 3, Improving Interaction
Chapter 4, Adding UI Elements
Chapter 5, Adding an Inventory
Chapter 6, Creating an Adventure

23
Getting Unreal
Getting Unreal
Welcome to what will be the start of an amazing adventure into the world of Unreal game
development using Blueprints. We're going to cover a lot of Material throughout this
book. Not only will it provide you with a solid foundation about Blueprints in terms of
what they do and how they work, it will also teach you some best practices along the
way. Ultimately, these will save you time (and stress) later on. The important thing to
remember as you progress through this book is that it is designed in a way to extend your
skills. Each project within this book will build on the skills from the previous one. Each
chapter and project will challenge you.
So, let's get going! In this chapter, we will cover the following topics:
Setting up Unreal and downloading the project files
Creating a new project and a level
Adding some basic lighting features
Interacting with lights in Blueprints
Placing objects in a level
Changing an object's Material through Blueprints
Using the Blueprint editor and connecting Blueprints together
Compiling, saving, and playing our game

24
Setting up Unreal and the project in this book
Setting up Unreal and the project in this book
To begin, if you haven't already, you can download the Unreal Engine here:
https://www.unrealengine.com/en-US/download.
Just to ensure that everything that we will create works as it should, we will be using
version 4.21.2 for this book. So, when you're downloading your copy, make sure it is this
version. The same will apply if you're using an older version, so make sure to update it!
With this said, let's cover a few basics about what Unreal Engine has to offer.

25
The Unreal Marketplace
The Unreal Marketplace
The Unreal Marketplace is a treasure trove for various amazing items that you can use
within your projects, of which only a tiny part is shown in the following screenshot. You
can get anything from environmental assets, audio, SFX, code, Textures, and even
Blueprints:

Image of the Unreal Engine Marketplace, as shown when you launch the Unreal Engine
dashboard
It doesn't stop there, either. Epic Games offers an immense amount of tutorials that can
help you out in all kinds of situations—from the basics such as importing assets all the
way to creating complex Blueprints or even code.
You can view the official documentation by visiting the following
link: https://docs.unrealengine.com/en-us/.
In addition, they also have a lot of video tutorials that can help out as well, which you
26
The Unreal Marketplace
can view by visiting the following link: https://academy.unrealengine.com.
Lastly, if you're like me and want to include Unreal Engine as part of your course, you
can find various guides that provide you with lecture slides, exercises, and projects that
your students can practice their skills with. Check them out by visiting the following
link: https://www.unrealengine.com/en-US/education.

27
Getting what we will need for our projects
Getting what we will need for our projects
Now, when it comes to the projects within this book, we will be using free content from
the Unreal Marketplace. The files that we will be using for each project, along with a link
to download them, are given in this chapter. With that said, feel free to use any other
asset pack that you may have to follow along with. Lastly, all the project files are
available so that you can download the levels both with and without the Blueprints. In
this way, you have the option to download both the finished project (including
Blueprints) or begin from scratch as you follow the tutorials in this book. You can find
the projects by visiting the following site: www.player26.com/community.
A quick note about downloading asset files. We know that sometimes large files can drain
internet quotas and can take some time to download, so it is not essential that you
download these asset packs since in some cases they are quite large. Therefore, just to let
you know (unless indicated), you can apply the Blueprints within this book onto general
primitive objects (for example, a cube, sphere, and so on) in Unreal.

28
Minimalistic platformer (Chapter 1 to Chapter 6)
Minimalistic platformer (Chapter 1 to Chapter 6)
Our first project will be a minimalist platformer. We are aiming for a basic aesthetic so
that we can focus on learning the fundamentals of Blueprints. Therefore, for this project,
we will be using basic primitives that are already in UE4. In particular, we will be using
the Soul: City asset pack from the Unreal Marketplace.

29
Survival maze explorer (Chapter 7 to Chapter 13)
Survival maze explorer (Chapter 7 to Chapter 13)
Our second project will be a survival maze explorer. By survival, I don't mean a zombie
apocalypse—I mean that once you die, it's game over and you need to start again. For
this project, we will be using the Infinity Blade: Grass Lands asset pack from the Unreal
Marketplace.

30
Sci-fi FPS (Chapter 14 to Chapter 19)
Sci-fi FPS (Chapter 14 to Chapter 19)
Our third and final project will be a multiplayer science fiction shooter. For this project,
we will be using the Infinity Blade: Grass Lands, Infinity Blade: Weapons, and Infinity
Blade: Adversaries asset packs from the Unreal Marketplace.

31
Creating our project for game #1
Creating our project for game #1
Our first project is going to be a minimalist platformer using some imported free game
assets from the marketplace. To begin, fire up UE4.
Once UE4 has opened, we're going to create a New Project. In this window, we will
select a Blueprint Template that our project will be based on. This provides us with
functionality that is related to the type of template. For example, the First-Person
template will have the camera position in a different perspective than that of Third-
Person (which is from behind the player). For this project, we will select Third-Person, as
shown in the following screenshot. What is nice about this window is that it also provides
an explanation about each of the Blueprint templates.
If you're new to this, take some time to read through the descriptions to get a better
understanding of them all:

32
Creating our project for game #1

Image of the New Project screen with project template options


Before clicking the Create Project button, we need to do two more things, the first being
choosing the device, its quality, and starter content.
For now, we will leave the settings as their default values, like in the following
33
Creating our project for game #1
screenshot. The second and last thing that we need to do is name our project and save it
in an ideal location. In the following screenshot, there is a folder path field and name. For
this project, I named the project MinPlatformer and stored it in the default Unreal
Projects folder of my PC.

Once you have set this up, click Create Project:

Image of the project settings screen


Once you have created the project, you will see a screen like the following:

34
Creating our project for game #1

Image of the UE4 engine workspace once you have loaded the Third-Person template

35
Naming conventions
Naming conventions
Before we get too deep into our project, I want to take a moment to talk briefly about
naming conventions. To illustrate the importance of this, it is the difference between
ripping your hair out later or chilling with a cup of tea. Maintaining a clear, meaningful,
and more importantly consistent naming convention is an essential part of improving the
development process.
Of course, you're free to create your own, but if you're unsure about where to start, there
is a great post on Epic's Wiki that can be accessed via the following link:
https://wiki.unrealengine.com/Assets_Naming_Convention.

36
What is a Blueprint?
What is a Blueprint?
Now that we have some objects within our environment, let's get started by learning
about what Blueprints are and how we can use them within our game environment. At its
core, a Blueprint is a form of visual scripting. What is meant by that is that instead of
writing lines of code, you can connect different nodes that have some functionality in
them to make things happen. This is not to say that this is for those who don't like code or
to replace coding altogether. At the end of the day, it is also a great tool for even the
experienced developer who would rather spend more time on other important parts of the
game. There are two types of Blueprints, which we will cover in more detail later in this
book:
Level: These are Blueprints that are only related to the level that they are created in.
Class: These are Blueprints that can be used across any level, and therefore throughout the entire game.
Moreover, it also allows us to expose parameters that we can use to toggle and vary the behavior of the
class.

For those who come from a traditional programming background with Unreal (C++), you
could create a class via a script and then expose it to a Blueprint so that others within the
team can tweak the functionality or expand upon it without touching the code. In this
way, it allows programmers, artists, and designers to work together and improve the
workflow of a game that's in development. Lastly, so that the terminology throughout this
book is clear, Blueprint refers to the language and Blueprints refers to the modular
functions that are created. In either case, we can use the common abbreviation BP or
BPs when referring to them.

37
Getting creative with Materials
Getting creative with Materials
Part of a game's ability to entice and entrance us with worlds of fantasy and adventure is
how they look and how they are played. In some cases, we see artistically extravagant
and complex environments (for example, Guild Wars 2, Assassins Creed: Odyssey), and
in others, we see aesthetically simple Materials but with a unique and eccentric approach
(for example, Monument Valley). In saying that, the use of Textures and Materials can be
computationally expensive. Fortunately, UE4 offers ways for us game designers to create
Materials that can run efficiently without compromising a game's functionality.
By now, you may be wondering, what about Textures? Aren't they the same thing?
Therefore, it is important to understand the difference between Materials and Textures.
The easiest way to think about this is that Textures are a part of a Material—whether it
be a single file or a 2D static image. The Material is what you will use to texture your
environment and apply to Static Meshes, and can contain many different Textures (for
example, normal, specular, diffuse, and so on).
In UE4, there are two different types of Materials, each working in a different way and
serving a different purpose than the other:
Material
Material Instances:
Constant: Calculated (only once) prior to runtime
Dynamic: Can be calculated (and edited) at runtime and during gameplay

The main difference between Materials and Material Instances is that a Material is a
single occurrence of a material, while a Material Instance can be replicated many times
without much cost to performance. Therefore, a Material Instance is like a clone of a
Material without carrying costly (computational) data.

38
Creating our first Material
Creating our first Material
In the Content Browser, right-click and create a new Material and call it
DynamicMatGlow. Then, double-click on it to open the Material Editor:
You can access all the Material nodes via the Palette Menu on the right, as shown in the
following screenshot. In addition, it also contains keyboard shortcut keys.

39
Creating our first Material
Screenshot of the material node
Create a Constant Three Vector by left-clicking and selecting
Constants | Constant3Vector. Alternatively, a keyboard shortcut to achieve the same
thing is 3 + left-click.
A vector parameter allows us to define a color by using red blue green (RGB),
Hexadecimal (Hex), or Hue, Saturation, Value (HSV):

Screenshot of how to locate Constant3Vector


Next, by dragging the output node from Constant3Vector to the Base Color node on
DynamicMatGlow, we can connect them, like in the following screenshot.

As we can see, while connecting nodes, a green tick will appear when it is possible to
connect the nodes—that is, they are being connected to the right inputs.
With the parts connected, double-click on our Constant3Vector and you will open the
Color Picker, as shown in the following screenshot:

40
Creating our first Material

Screenshot of the Color Picker inside of UE4


To choose a color, we can either enter it manually in the RGB, Hex, or HSV components,
or we can choose it via the Color Wheel. For our glowing sphere, we will use a bright
yellow color. The RGB values for the color are 1, 0.9, and 0. Feel free to make your
sphere whatever color takes your fancy. Once you select the color that you're happy
with, you will notice a change of color within our vector parameter node, like so:

Screenshot of the RGB values of a Constant3Vector


While we are in the initial stages of developing our Material and even Blueprints, it is
important to keep all the nodes organized. Doing this early on saves us a lot of pain and
41
Creating our first Material
tears later.
Now, we need to convert our vector node into a Parameter. This is so that we can easily
change various features (for example, the color) when we apply this Material to other
objects. Think of it like a customizable option that we can change externally without
having to go back into the Material Editor. To do this, right-click on the vector node,
select Convert to Parameter, and give it a name. We will call it GlowOrbColor since that
is what it is. Once you have done this, the node will change, like in the following
screenshot:

Screenshot of the Constant3Vector after is has been converted to a parameter

42
Giving out material that glow effect
Giving out material that glow effect
To create a lovely glow, we need to get a little mathematical. Don't worry – it's quite
simple to understand. We will be using the Sine Wave, which (in the following screenshot
in this section) might look familiar to you. Now, why a sine wave?
So, as the numerical values change between 1 and -1, we will get a change in color
(light/dark). To get that glowy feeling, we need to modify the frequency. This is basically
how fast the change in color occurs (between 1 and -1).
If you're unfamiliar with Material nodes, we will be using a few new ones:
Time: This is a global parameter that is based on the engine's internal time. It
will start as soon as the game/editor starts and increases.
Scalar Parameters:
Frequency: This refers to how often the wave occurs (fast or slow) in terms of
our glowing effect. A short wave (high frequency) will make it strobe and a long
wave (low frequency) will make is fade in and out longer. The latter is what we
want.
Intensity: This refers to the level of brightness/glow of our Material.
Multiply: This takes two inputs, multiplies them together, and outputs the result.

Sine: This refers to the Sine Wave.


First, we will begin by creating some nodes and then we will connect them:
1. Begin by adding a Time node by right-clicking and selecting Constants | Time.
2. Now, add a Multiply node. To do this, right-click and select Math | Multiply. Alternatively, you can
hold down the M key + left-click.
3. Now, add a Scalar Parameter by right-clicking and selecting Parameters | ScalarParameter. Call it
Frequency. In the Details Panel (on the left), give it a Default Value of 1.
4. Connect Time to the Multiply node via A and the Frequency node via B.
5. Then, add a Sine (wave) node. To do this, right-click and select Math | Sine or just search for it in the
search box. In the Details Panel, adjust the Wave value as you please. The value itself refers to seconds
within the game engine. Therefore, the larger the value, the slower the glow.

43
Giving out material that glow effect
1. Now, connect the Multiply node output to the Sine node.
2. Break the link between GlowOrbColor and Base Color by right-clicking on Base Color and selecting
Break Links.
3. Next, create another Multiply node.
4. Connect the RGB connector of GlowOrbColor to the Multiply node via A and the Sine output node via
B.
5. Create another Scalar Parameter, call it Intensity, and give it a Default Value of 1.
6. Create another Multiply node and connect the output of the previous Multiply node via A and the
Frequency output node via B.
7. Lastly, connect the Frequency output node to the Emissive connector of DynmaicMatGlow.

The final setup should look as follows:

Screenshot of our Material Node setup


If you want a glow that is more like something you would see with the Bloom Effect, you
will need to increase the value of the Intensity to around 100. Essentially, the higher the
number, the more dramatic the effect.
Of course, you can increase the rate of Frequency to a higher value, but keep in mind
those (creators and players) who may have epilepsy.

44
Using Materials with Blueprint
Using Materials with Blueprint
For this project, we are going to create a Material that can be changed if you get close or
move away from it. By doing this, we can get an idea about a Material's node structure,
followed by a basic dynamic Material in Blueprint. We will cover more complex dynamic
Materials in Chapter 11, Making it Pretty, but for this chapter, we will cover some basic
dynamic Materials such as a glow effect and how to use Blueprints to modify Materials.
Before moving on, here are some keys on how to navigate blueprint graphs. You can
zoom in with the wheel and scroll by holding down the right mouse button.
Before we get started, let's create a folder for our Materials. You can do this by right-
clicking in the Content Browser and selecting New Folder, like in the following
screenshot:

45
Using Materials with Blueprint
Screenshot of the UE4 interface, with the Content Browser highlighted
Once you have done this, call it something that is relevant. In this instance, we'll call the
folder Project Materials.

46
Dynamic Materials – the GLOW
Dynamic Materials – the GLOW
So far, we have learned a lot about other very powerful systems in Unreal. We did this
because all of them can interact with Blueprints, and having a foundation about how they
work is key.
In this section, we will get a taste of what blueprint is capable of before moving deeper
into it in the next chapter. In fact, it's time to create our first blueprint class. Don't worry
if it looks complicated, or if you don't fully understand it. In fact, blueprint should be
learned iteratively, in which each piece will make sense at some point in the learning
process.
To begin, let's create a base Blueprint. In the Project Materials Folder, right-click and
select Blueprint Class. A dialogue box will appear, asking you to select the Parent Class.
For this, we will select Actor, as in the following screenshot. An actor is something we
can place in our scene, so it is one of the most common classes that's used. Don't worry
about the other classes for the moment—we will go through them later in this book:

47
Dynamic Materials – the GLOW
Blueprint class selection
Now, call it BP_DynamicMat (Dynamic Material Blueprint) and then double-click on it
to open it up. When you have the editor open, we will need to add a component to our
Blueprint.
To do this, follow these steps:
1. Select +Add Component in the top left corner
2. Then, select Static Mesh
3. Now, in the Details Panel, find Static Mesh
4. Select the drop-down next to Static Mesh
5. Then, select MaterialSphere
This process is outlined in more detail in the following screenshot:

48
Modifying the Material in Blueprints
Modifying the Material in Blueprints
Now, it's time to get into Blueprints! In the Content Browser, double-click on
BP_DynamicMat to open the Blueprint Editor, which should look as follows:

For now, ignore that there are already three nodes in the blueprint. It's time to create our
own nodes and build our first simple logic!
A blueprint graph is where we can specify the logic of the blueprint we are editing. It is
called a graph because it is mainly composed of nodes and connectors. This can be
overwhelming at the beginning, but you will get used to it. For now, just follow along here
and we'll go through it all in detail. At the top of the menu, there's is a search bar, and
when we start typing, we can search for the node that we need.
The logic we are going to build is as follows:
1. As soon as the game starts, we are going to create a dynamic Material instance
49
Modifying the Material in Blueprints
2. Then, we will save this Material into a variable so that we can use it at later a stage
3. Next, we modify the Material, and in particular, we change its color
4. Finally, we assign this new Material to the static mesh that we have in our blueprint actor

We'll now move on to the steps for the same:


1. From the Event BeginPlay node, drag the little arrow to start creating a connector and release it
somewhere nearby. As a result, a menu will appear, showing a very long list of possible nodes
(ordered into categories) that we can connect to, as follows:

2. In particular, type in Create Dynamic Material Instance and select the one that contains Static Mesh in
brackets, as shown in the following screenshot:

3. Once selected, this is how our graph will appear so far:

50
Modifying the Material in Blueprints

4. We can rearrange the nodes by dragging them, and we can untie the connectors. You will find yourself
doing this operation a lot while creating Blueprint graphs, and I suggest doing it often to avoid ending
up with a messy Blueprint.

Try to minimize connectors crossing over each other (like in the preceding screenshot) to
make it easier to read. Later in this book, we will learn some tricks to make this process
easier.
5. In the Dynamic Material Node, we need to select the Glow Material we have created so far, in
particular, the first one, DynamicMatGlow:

As you can see, not all of the connecting wires are the same color. The connector
from Static Mesh to the Create Dynamic Material Instance node is blue. This is
51
Modifying the Material in Blueprints
because that is a reference to an object. This will become clearer later in this book.
At the end of the Create Dynamic Material Instance node, there is a white arrow,
which will, as a flow, tell the Blueprint what to do next. So, the white connectors
are important, since they represent the way a blueprint graph is executed. At the
bottom of the node, there is a return value, which is a reference to the Dynamic
Material Instance we have just created. Since we want to use it again later, we
need to store this reference somewhere.
6. If we right-click on it and click on Promote to Variable, our graph will update:

This means that the flow (the white connectors) now go into another node. This has
created a variable for us for storing that specific reference, and a blue
connector from the create Dynamic Material Instance into the SET node.
Also, note that down on the left, a new variable appeared, named New Var 0, as
you can see in the following screenshot:

52
Modifying the Material in Blueprints

7. If you select this, you will be able to modify some of its properties in the detail panel on the right. For
now, we just want to modify the name to something meaningful, such as OurDynamicMaterial:

53
Modifying the Material in Blueprints

8. The next step is to drag a blue wire from the SET node (from the little circle down to the bottom) and
add a new node, like we did before. The same menu will appear, but this time it will show only the
nodes that can have our dynamic Material reference as input (in fact, we are dragging our blue wire).
This time, we will choose the Set Vector Parameter Value node. Once in place, it will look as follows:

Please note how a white connector has also been dragged out from the SET node
into this new one: Set Vector Parameter Value.
9. Now, we need to change the parameter name so that it matches the same name we gave in our Material
when we converted the color into a parameter. Then, double-check that the name is exactly the same ,
otherwis,e it will not work. In our case, it was GlowOrbColor. Then, just down below, if we click the
black square, we can pick any color. In this case, we have picked green. This is the end result:

54
Modifying the Material in Blueprints

10. Finally, the last step is to assign this new material to the static mesh. So, from the Components panel on
the right, drag the static mesh into the graph. Now, drag out a connector from the new static mesh node
and select/search for the Set Material node.

11. Now, we need to connect the white arrow of the Set Vector Parameter node, into the new Set Material
Node. Then, we need to drag from the left screen our variable, OurDynamicMaterial, and release it on
top of the Set Material node, in particular into the material parameter. This is the end result:

12. Now, we can compile our Blueprint, which is an operation in which Unreal checks if everything is okay
in our Blueprint. This doesn't guarantee that our Blueprint will work as we want it to. Rather, it will
check that there are no errors, such as missing things. Then, we can save it. Both of these operations can
be done with the respective buttons in the top bar, as shown in the following screenshot:

13. If the compile process went without errors, this is how the icon will appear:

55
Modifying the Material in Blueprints

Otherwise, you will see something like the following icon:

14. Moreover, at the bottom, there is a console, which will give you some information regarding the issue.
If you click on the highlighted text, it will bring you to the node where the problem has occurred, and a
label below the node will show you that there is a problem on that node:

In any case, for the simple Blueprint we have written, there shouldn't be any problem.
Here is an overview of what we have done for your reference:

Once we have compiled and saved our blueprint, we can close our blueprint editor and go
back to the main interface of Unreal. Here, we can finally drag our blueprint actor into
the scene, next to the other three cubes if we haven't already done so before. As you will
be able to see, in the beginning, the sphere is grey, but as soon as we press play (the
button on the top), it will become green.
56
Modifying the Material in Blueprints
Congratulations! you have created your first blueprint. Once again, it's not important
whether you have understood everything, because programming in Blueprint is something
that needs to be learned bit by bit, so stick with me for the rest of this book—you will be
able to create nice and complex blueprints!

57
Adding some light into our environment
Adding some light into our environment
Let's light up our scene! We will begin by adding some basic lighting to our scene.
There are quite a few options when it comes to adding lighting to a game's environment,
and designers will add this at various stages of a game's development. Lighting is in no
way a static part in the development of the game but an ongoing and dynamically
changing part. This is to say that as a level begins to grow, objects will affect how lighting
influences the atmosphere of a game. There are many different types of lighting in
Unreal:
Point Light: This works much like a real-world light bulb, emitting light in all directions from its
center.
Spotlight: This emits light from a single point in a cone shape, just like the ones in the theater or when a
helicopter is searching for something or someone.
Sky Light: This works a little different to, say, a spotlight or point light because it captures the distant
parts of your level and applies that to the scene as a light.
Directional Light: This simulates light that is being emitted from a source that is infinitely far away.
Think of it like the sun emitting rays of light. You can't see (unless you add something to represent it) it,
but you can see its effect. As the name suggests, its directional meaning is that it will cast shadows in
the direction that it is pointing in.
Modulated Lighting and Shadows: These are like dynamic shadows that are cheaper in terms of
rendering cost but less realistic. They are ideal for mobile games/apps.
Post Processing: This isn't a light per se, but it can influence the way light appears in your game. Think
of it as the final touches in your game such as color balancing, ambient occlusion, tonal mapping, and
the one of the most popular, the bloom effect.
Light maps: This stores lighting information for an object via a texture. In other words, it tells the
engine how light should affect an object.

The preceding descriptions are quite brief, but don't worry—as we progress through this
book, we will learn about them in more detail, along with their practical application by
using Blueprints. For this part of the project, we're going to be creating a basic lighting
setup, but we will cover more advanced lighting as we progress throughout this book.
For our first project, we are going to be using mainly Point Lights and Emissive Materials
(like we created earlier).

58
Using lighting with Blueprint
Using lighting with Blueprint
Let's start by creating another Blueprint Actor, which we will name BP_OurFirstLight.
We will do something similar to what we have done to our BP_DynamicMat. In fact, we
will change the color of the light once the game starts.
In a similar fashion in which we created the static mesh on the other Blueprint Actor,
here, we are going to create a point light:
1. Go to the Graph Editor and drag the light from the component panel into the graph.
2. Then, drag a connector from the light to create another node named Set Light Color:

3. Now, drag a white connector from the Event BeginPlay into the Set Light Color node and change the
New Light Color variable to any color you like. In this case, I'm going for the color red:

4. Compile and save your Blueprint before exiting the Blueprint Editor.

Finally, we can place our Blueprint Actor in our environment. As we can see, it's white,
but as soon as we press play, the light will become red. We have now seen how easy it is
for a blueprint to change things. In the next chapter, we will venture deeper into the
Blueprint realm.

59
Extending upon what you've learned here
Extending upon what you've learned here
If you want to push what you have learned here a little further, the following are some
exercises to get you going:
Experiment with plugging the Color Parameter Node into other channels
Create different versions of the Glow Material (for example, flashing light, slow glow, and so on)
Try adding a different base color and glowing color
Experiment with changing the different color values for our Material
Find an asset online, download it, import it, and give it a new Material
Try to make the color of the sphere revert back when you move away from it

60
Summary
Summary
Congratulations! You have built your first Blueprints! What an awesome start! In a
parallel universe, I am sure we are celebrating together and eating cake. For now, I hope
my written enthusiasm keeps you going. As for what we have covered in this chapter, we
first downloaded the files that we needed, created and set up our project for our first
game, along with the importance of naming conventions. Next, we were introduced to the
central concept of this book—Blueprints. We learned about what they are and how they
work. Then, we learned about how to create basic Materials using Blueprints, followed
by how to create lights and how to allow the player to interact with them.
In Chapter 2, Understanding the Basics of Blueprints, we will extend upon what we
have learned. We'll look at some best practices when creating Blueprints and how to
apply more complicated Blueprints to the objects within our level. Next, we will learn
how to create collisions for various types of objects. Lastly, we will conclude the chapter
by learning how to create and activate triggers within our game.

61
Understanding the Basics of Blueprints
Understanding the Basics of Blueprints
Now that you have had your first taste of UE4 and Blueprints, it's time to challenge
ourselves. But fear not, as we're going to slowly increase the complexity of what we did
in the last chapter. For now, we're going to learn a bit more about the different Blueprint
types and then how to apply them to objects to make them move and trigger events.
To summarize, in this chapter, we will do the following:
Look at some (important and key) best practices when creating Blueprints
Next, we will dive deeper into what level and class Blueprints are and how to apply them within our
level as well as to objects
Then, we will learn how to create collisions and triggers in UE4 for different types of objects
Lastly, we will conclude this chapter by learning how to create a moving platform using Blueprints

62
Overview of Blueprint and its workflow
Overview of Blueprint and its workflow
In Chapter 1, Getting Unreal, we learned about some simple Blueprints to get us started.
By now, you should have a pretty good idea of what they are and how they work. Here,
at the beginning of this chapter, we will explain the workflow for using Blueprints and
some best practices before we start creating more complicated Blueprints. For example,
when creating your Blueprint, regardless of the context, you will want to make sure that
your Blueprints are efficient and succinct. You don't want to make a Blueprint execute
twenty different commands when not all of them are needed or when they can be
executed within a function of its own when it is required.

63
Speed
Speed
Speed in all senses is important. The speed of a computer (CPU/GPU), the speed at which
a function is executed, and the speed of an AI being able to respond are all important
elements to consider. When it comes to Blueprints, the speed at which a Blueprint can
execute a function and its (consequently) features in-game is crucial. While in some cases
this cannot be observed (for example, tenths of a second), many tenths of a second can
add up. This is especially important when there are many Blueprints operating at the
same time and in an online context.

64
Color schemes
Color schemes
This falls along the same lines as naming conventions. For example, for parts of your
Blueprints that are the beginning, an event is colored green, anything that involves
movement is purple, anything that involves interaction can be orange, and so on.
Try and find a color scheme that works for you and one that you will find easy to
remember. If you have to, write it down somewhere and if you're sharing the Blueprints
among a team, keep it somewhere obvious.

65
Introduction to level and class Blueprints
Introduction to level and class Blueprints
There are several types of Blueprints within UE4: Level, Class, Data-Only, Interface, and
Macro Library. For this chapter, it is important to know the difference between two of
these: Level and Class. This is because they serve different functions, especially when it
comes to handling different levels within your game.

66
Level Blueprints
Level Blueprints
The information contained in a Level Blueprint can only be accessed by the level it is in.
In essence, a Level Blueprint is a type of Blueprint that influences events within a
specific level. Each level that you create will have its own Level Blueprint. It is
important to keep in mind that you cannot create additional Level Blueprints. You can
only find the Level Blueprint via the editor menu under Blueprints, as indicated in the
following screenshot:

Image of where the Level Blueprint is located

67
Class Blueprints
Class Blueprints
The other blueprint classes can be accessed even while the player is passing through a
phase. A Blueprint Class—or simply a Blueprint—adds functionality on top of existing
gameplay classes. At their core, Class Blueprints define a new class or type of Actor,
which we can place into our maps as instances that behave like any other type of Actor.
We will briefly discuss the following Actors and other Class type Blueprints, which will
also become relevant in other projects later in this book:
Actor: are objects, which can be placed or spawned in the world.
Pawn: is a type of Actor that can be possessed and receive input from a Controller

Character: it's a Pawn which possesses the ability to walk, run, jump, and more
PlayerController: an Actor that controls the Pawn, which is used by the player.
Game Mode: defines the game being played. For example, it defines the rules,
scoring, and other aspects of the game type.

68
Detecting collision
Detecting collision
When you think about games, I am sure that you know that it is highly unlikely that you
will walk through walls, trees, or even characters. This is because when we collide with
any of these or other in-game objects, the game detects a collision and stops us. A game
stops us from colliding with an object because each un-collidable object has a collider.
Depending on what the object is, we use a different collider.
The main types of collision mesh are as follows:
Sphere Simplified Collision is best used when an object is spherical in shape. For example, balls,
glowing orbs, and so on.
Capsule Simplified Collision suits object that Sphere collision is not suitable for. For example, bullets
and even some characters.
Box Simplified Collision is probably the most usable type of collider, given that it can be adapted to
many different kinds of objects without having to worry about the excess that would be given from a
Sphere collider.

You may be wondering at this point: what about objects that are a bit more
complicated? Like an intricate piece of weaponry or an extravagant vehicle? Well,
luckily, in UE4, you can actually use the mesh itself for collision. Why not do this for
everything? This is simple—optimization. The more complicated the collision, the more
resources it will require to make it work in-game. Imagine you have a mesh that has
10,000 vertices. The engine is then checking every vertex of the mesh up to several times
per frame. That takes a lot of processing power. Try to stick to this—they are
simplified for a reason.
If you have a complicated mesh, try subdividing your geometry for improved graphics
and collision performance.

69
Trigger happy – how to create triggers and activate them
Trigger happy – how to create triggers and activate
them
Whether you want to trigger a trap or a series of (un)fortunate events, triggers allow
games to feel dynamic and provide consequences for our actions. Just like our colliders,
triggers differ in shape (box, capsule, and sphere) and thus so does their area of influence.
There are many different events that you could use to trigger an event. The main events
typically happen in response to a collision with another object. For example, something
(for example, a player) hitting or overlapping with the Trigger (for example, a switch to
activate a door), or in response to input from the player (for example, a player smashing a
chair).
In our scene, we will create triggers for both our light and material. For now, we're
keeping it simple, but we will create more complicated triggers later in this chapter.

70
Triggering an event using Blueprints
Triggering an event using Blueprints
We need to trigger an event within our level using Blueprints. We will be using the
Blueprints that we created from Chapter 1, Getting Unreal, so if you have decided to
start here, you will need to refer to those Blueprints. To do this, follow these steps:
1. Start with the Blueprint that we called BP_DynamicMat.
2. We will now need to add an Add Component to do this, so select Add
component | Collision | Box and then call it TriggerBox. We will need to scale it
accordingly to the size of both our object (box) and space where we want to initialize
the trigger.
3. To scale the box, you will need to head over to the Viewport, and select the Trigger
Box. In the Details Panel, you can adjust the scale as you like. For the purposes of
this section, we'll increase it by 20. You can see an example of this in the
following screenshot:

71
Triggering an event using Blueprints

4. Now, we are going to actually define the type of trigger that we want to initiate. For example, when the
player overlaps, enters, exits, and so on, they will have hit a trigger. To do this, within the Details
Panel of the trigger box, go to Events and click on the plus sign next to On Component Begin
Overlap, like in the following screenshot:
72
Triggering an event using Blueprints

5. Once you have done this, you will create an event in the graph, as shown in the following screenshot:

6. There are quite a few nodes that we can use to connect to various things. For this
part of this book, we'll be focusing on the Overlapped Component.
7. From here, we need to check if the object that has been entered is the player. We are
going to do it drag and add a (Third Person Character) Cast. To add a Cast, begin
typing Cast into the search bar and select Cast to ThirdPersonCharacter, like so:

73
Triggering an event using Blueprints

8. Finally, connect the Other Actor pin of the Begin Overlap node to the Object pin of the Cast To node.

74
Cast To…
Cast To…
At this point, you might be wondering what Cast To is. Since we will use this quite a bit
throughout this book, it is important to have a basic understanding of what it does and
how it works. To put it simply, a Cast allows us to check if the Actor is the third person
character that is controlled by the player. Therefore, we can check if the player enters
inside the trigger box.
To look at how Cast To works at a more technical level, we can think of it in terms of
parents and children. In Blueprints, Actors (for example, a character, pawn, and so on)
can be parented off of one another. What this means is that you can have a hierarchical
structure where each subsequent item inherits properties of the other.
For example, consider the following example. We have the main Actor—Vehicle. It may
contain some basic parameters like acceleration, deceleration, brake, and so on. But
then you have two child Actors—Two and Four Wheel—that contain different
properties. For example, two-wheel vehicles have no gear changes, whereas four-wheel
vehicles do. From here, each of these child Actors has their own children, each with their
own properties.
Now, why all these additional children? I'm simple. Imagine that you have in-game
pickups like fuel. Not all vehicles consume fuel the same way or at the same rate. For
example, a Scooter is more likely to consume less fuel than a Truck. So, during gameplay
and while the player is driving a vehicle, this needs to be reflected in terms of the
availability of pick-ups, how much fuel each vehicle needs before their tank is full, and so
on:

You can find more detailed information about blueprints here:


75
Cast To…
https://docs.unrealengine.com/en-us/Engine/Blueprints/UserGuide/CastNodes.
Now, we need to connect the Cast so that it actually does something – that is, change
color:
1. For this, we need to create a Set Vector Parameter Value .
2. To do this, drag the Output Node and start typing in the search bar VSet Vector Parameter Value .
Then, select it.
3. From Set Vector Parameter Value , drag the Target pin (from the node) and start typing Our
Dynamic Material.
4. Then, select Our Dynamic Material. Once you have finished, your Blueprint should look as follows:

76
Triggering an event using Blueprints – moving a platform
Triggering an event using Blueprints – moving a
platform
As the title suggests, we're going to be moving something. Now, what that something is
can be up to you. For now, we will create a (horizontal) sliding platform that will be
triggered by a collider. The point of this section is to show you how, using two examples,
to trigger not just another type of event, but a useful one. Can you think of a game where
there was nothing sliding up or down?
We've all seen one, whether it's in Tomb Raider or Crash Bandicoot—they exist and
offer different experiences from adding a bit of challenge to a rage quit, and everything
in-between:
1. To begin, we're going to create another Blueprint Actor Class, call it BP_MovingPlatform, and then
open it in the Event Graph.
2. Here, we will need to add a platform, so click Add Component | Cube and call it MovingPlatform.
3. Drag it onto DefaultSceneRoot to make it the parent of everything else that we will now do within the
Blueprint, especially when we are using it within our game.

We need to make it look more like a platform. So, with the Viewport Window selected,
head on over to the Transform section of the Details Panel and adjust the Scale until you
get something that you like. For this example, we chose (X)3.0 (Y)2.0 (Z)0.3:

4. If you want to scale all the sizes equally and at once, make sure to close the padlock, like in the
following screenshot:

77
Triggering an event using Blueprints – moving a platform
The top is where the padlock is disabled (open) and the bottom is where the
padlock is enabled (closed).
5. We are going to add a collision to our MovingPlatform via Add Component | Box Collision (you will
have to type it into the search field). Once we have found it, we'll call it MovingPlatformCollision.

6. We will need to resize the MovingPlatformCollision mesh so that it fits our MovingPlatform better.
Head over to the Transform section of the Details Panel and adjust the Scale until you get something
that you like. For this example, we chose (X)1.5 (Y)1.5 (Z)0.8.
7. With MovingPlatformCollision selected in the Components Window, head over to the Viewport
Window, select the Translate tool (or press the W key), and move MovingPlatformCollision until it is
just touching the top of MovingPlatform. An example of this is shown in the following screenshot:

8. Since we already have a starting point with the initial Translation values, we need to add one more
collider, which will determine where MovingPlatform will finish. So, add another Box Collider, call
it MovingPlatformEnd, and increase the Z (Scale) value to 5.0. You should have something that looks
as follows:

Once you have done this, it is time to head on over to the Event Graph to start making
78
Triggering an event using Blueprints – moving a platform
this platform move! Let's see how we can do this:
1. To begin, we can remove the bottom two nodes, as we only need the EventBeginPlay one for now.
2. From the My Blueprint panel on the bottom left, and while holding down Ctrl, drag (to Get)
MovingPlatform into the Event Graph.

1. Drag the output node and type (then select) Get World Location. We're doing this so that we can get
the locational coordinates of where the MovingPlatform is in relation to the world space.
2. Then (in the My Blueprint Panel), create a New Variable by clicking on the + symbol. We will call
this variable StartLocation.
3. On the right-hand side of the Details Panel, change the Variable Type to Vector. This is because we
need to get three values (X, Y, and Z).
4. While holding the Alt key (to Set), drag this variable (from the Component panel on the bottom left) out
into the Event Graph.
5. Drag the output node from GetWorldLocation and place it into (SET) Start Location.
6. Drag the output node from Event BeginPlay into the input node of SET. Once you have done all of this,
you should have something that looks like the following:

Everything that goes up must come down. Everything that starts has an end.
1. We need to create another Variable . We will call it EndLocation and make sure that its type is Vector
as well.
2. While holding Ctrl, drag our MovingPlatformEnd into the Event Graph.
3. Connect the output node of MovingPlatformEnd to the Target node of GetWorldLocation.
4. Connect the Return Value node to (SET) End Location.
5. Drag the output node of our first (SET) End Location for our MovingPlatform and connect it to the
input node of our second (SET) End Location for our MovingPlatformEnd. Once you have done this,
it should look as follows:

79
Triggering an event using Blueprints – moving a platform

6. Next, in the Components panel, right-click on MovingPlatformCollision, select Add an Event, and
select OnComponentBeginOverlap.
7. Then, while dragging from the Other Actor node, type (and select) Cast To ThirdPersonCharacter.
8. Now, while dragging from the output node of the ThirdPersonCharacter type (and select), Add
Timeline and call it PlatformTime.
9. Then, double-click on PlatformTime and add a Float Track by clicking on the following highlighted
icon:

10. For now, let's rename the track to PlatformFloatTime.


11. Now, change the Length to 1:00.

12. Then, within the Track Editor, we need to add two keyframes, one at 0 and another at 1. We can do this
by right-clicking and selecting Add Key, and we can change the value by selecting the keyframe and
then by changing the value, as in the following screenshot:

80
Triggering an event using Blueprints – moving a platform

13. Back in the Event Graph, we need to Ctrl and drag MovingPlatform from the Components Panel into the
Event Graph.
14. Now, from MovingPlatform, drag the output node and type in (then select) Get World Location.
15. Then, drag from the Update execution pin (from the PlatformTime node) and connect it to the execution
input pin (white wire) from the Get World Location node.
16. Next, drag the PlatformFloatTime node from the PlatformTime node and type in (then select) Lerp
(Vector).
17. Now, connect the Return Value node on Lerp (Vector) to the New Location node on
SetWorldLocation. You should have something that looks as follows:

18. Then, we need to create a Start Location and End Location. To do this, drag the A node on Lerp
(Vector) and type (then select) Get StartLocation.
19. Do the same on the B node, but instead type in (then select) Get EndLocation. It should look as
follows:

81
Triggering an event using Blueprints – moving a platform

Now, return to the level editor. We are going to add our platform and test to see if
everything is behaving like it should:
1. From the Content Browser, drag our BP_MovingPlatform into the level and adjust its position
accordingly.

2. Next, select the MovingPlatformEnd from the Details Panel (like in the following screenshot) and
move it to a location within the game environment where you want the platform to finish:

82
Triggering an event using Blueprints – moving a platform

Now, it's time to put it in reverse gear and have our platform go back to where it started.
The process for this is relatively simple and pretty much the same as for making it go
forward:
1. To begin, in the Components panel, right-click on MovingPlatformCollision, select Add an Event,
and select OnComponentEndOverlap.
2. Then, while dragging from the Other Actor node, type (and select) Cast To ThirdPersonCharacter.
3. Make sure that the OverlappedComponent in OnComponentEndOverlap is connected to the Object
Actor node in Cast To ThirdPersonCharacter.
4. Now, drag the output node from Cast To ThirdPersonCharacter and connect it to the Reverse node in
PlatformTime.

And that's a wrap—for now, at least. Test your platform and change some settings to
make it move as you please. Now, it's time to move on to the next part of our project.

83
Extending upon what you have learned here
Extending upon what you have learned here
If you want to push what you have learned in this chapter a little further, try completing
the following exercises:
Try to create a trigger for a different event
Try restoring BP_DynamicMat to its original color (HINT: you can find it in the Events part of the
Details Panel)
Experiment with using different collision and trigger shapes
Try using another object to trigger the sliding platform or door
Modify the Float track and other variables to change the speed of the platform
Try to create a sliding door instead of a platform (HINT: think about the shape and scale of the platform
as well as the placement of triggers)

84
Summary
Summary
You've reached the end of this chapter. So, let's take a moment to look back at what we
have achieved.
You have built your first collision and trigger Blueprints! Thankfully, we haven't
destroyed anything…yet. We learned about some best practices when creating Blueprints
in more detail. Then, we learned about the differences between different types of
Blueprints, focusing more on level and class types. This was then followed by creating
some triggers for activating platforms and changing material colors with the help of
colliders.
In Chapter 3, Improving Interaction, we will learn about interfaces for objects and how
to create them. In addition, we will also learn about creating Blueprint functions, when
they are appropriate to use, and how to make them easy to be read by others, as well as
how to create modular and reusable Blueprints. Lastly, we will learn about creating
rerouting nodes, which is something that will come in quite handy throughout the projects
in this book. So, let's keep going!

85
Improving Interaction
Improving Interaction
We will now move on to improving interaction. Let's continue our journey by exploring
the wonderful world of interaction and interfaces. In this chapter, we're going to learn
how to implement more advanced concepts of Blueprints in relation to interaction. More
specifically, we'll cover topics on the following:
Blueprint functions
Keeping your Blueprints easy to read, modular, and able to be extended upon or reused later
Rerouting nodes and comments
How to implement interfaces using Blueprints
Blueprint interfaces for interactable objects

In particular, we are going to learn a little bit about functions and how to keep our
Blueprint tidy, before we move on to a more complex topic: using interfaces to trigger
interactions.
So, let's get down to business!

86
Blueprint functions
Blueprint functions
Now, what exactly is a Blueprint function? Whether you are familiar with a (any)
programming language or not, the concept of a function is easy to grasp. Imagine that you
need to do a repetitive task over and over again, except with slightly different data. For
example, imagine that you need to calculate the area of a triangle. To do this, you need to
multiply the base and the height and then divide by two. Then, if during your game for
some strange reason you need to calculate the area of a determinate triangle, you don't
want to write a different Blueprint graph for each triangle – rather, you want to create a
function.
With this in mind, you can think of a function as a container that holds a list of
instructions, and each time that you want to access those functions, you just get (or
call/reference within the code or Blueprint) that container.
In this sense, a function is a piece of code (or just a sequence of instructions) with some
parameters. This function can be used repeatedly for accomplishing a task.
In the context of a Blueprint, there are many kinds of functions, but they have different
names (since they behave slightly different). We have the following functions:
Functions: As the name suggests, they do exactly what we described in the previous paragraph. They
have inputs and outputs. You can create a new function from the menu on the side inside the Blueprint
editor, as shown in the following screenshot. Moreover, you can also override functions in case you
also want to inherit a function from a parent, but you want to override it (change it and/or extend it).
Don't worry about this for now:

87
Blueprint functions
Macros: You can imagine them as functions, but underneath they work differently. In fact, a function is a
separated context, whereas a macro is a shortcut to substitute parts of the graph that repeats. You can
create Macros from the same side menu, as shown in the following screenshot. At the moment, we are
not using Macros:

Event: Events are special functions that can be called from other Blueprints. They have support for
replication (when you plan to build an online game) and much more. However, this can be confusing at
the beginning, and so, for now, we are going to use the basic functionalities of events. In particular, as
the name suggests, we are going to use them to trigger an event and call events from different Blueprints.
You can create an event by right-clicking on the graph and then selecting Add Custom Event…:

In this chapter, we are going to use mainly Events, but throughout this book, we will see
them all. But before to jump into how to create an interface, let's see how we can make
88
Blueprint functions
our Blueprint easier to read.

89
Keeping your Blueprints easy to read and to extend
Keeping your Blueprints easy to read and to extend
As we covered in Chapter 2, Understanding Basic Blueprints, it is important to have a
good workflow. It is also equally important to make sure that your Blueprints are easy to
read and are annotated (we will discuss this in the next section).
So, where do we begin to improve the readability of our Blueprints? Glad you asked.
We have already learned about functions and events. Well, this is a good starting point
when planning for readable and easily extendable blueprints. If you try to divide your
code into different chunks, or different function calls, this will make it easy to understand
what the Blueprint is doing in general.

90
Reroute node
Reroute node
Sometimes, when you start creating complex Blueprints, they can get messy and this can
happen very quickly. As a result, it's good if, once in a while, you reorder the graph, try
to simplify it, and so on. However, sometimes, it's not always possible to reduce the
number of connections. Thus, a useful tool is the rerouting node. It doesn't actually do
anything, and as the name suggests, it helps you reroute connections. You can add it like
any other node. Then, you plug a connection and drag another one out into the final node
you want (or potentially in another reroute node as well). This is what this node looks
like:

91
Sequence node
Sequence node
Another specific tip when programming in Blueprint might be to use the Sequence node.
This node does nothing special, but it helps by giving a structure to what you are doing. In
basically forces you to create subgraphs that are executed in sequence, forcing you to
understand which is the process underneath what you are trying to accomplish.
This is what a sequence node looks like:

You can add as many pins as you like. Moreover, you can connect each of the pins to a
function call. As a result, with just a glimpse, you are able to understand the general
workflow of this Blueprint. Also, if you use the sequence node in combination with the
reroute node, you can create very clean graphs, like the following one:

92
Sequence node

Of course, this structure becomes more and more useful when we have a long sequence
of tasks.
Be careful as having too many functions or sequence nodes can have the opposite effect
and confuse ideas. So, if you have a Blueprint with dozens of functions, each one of them
doing just a little task (for example, adding two numbers together and calculating a
distance), you need to rethink your structure. Do not add too many levels of functions,
because navigating through that many functions might make you lose focus.

93
Comments
Comments
I cannot express enough (especially if you work in a group) the importance of comments.
Comments (along with testing) are the most vital thing to ensure that not only you but
others know what is going on within your Blueprints.
Now, this isn't a suggestion to comment on everything, because that would be silly. What
is meant by commenting here is that for parts of your Blueprints that are complicated or
even for parts that you may want others to tweak (for example, artists/designers), you
want it easy for them to know what's what.
You can easily add a comment by selecting a group of nodes, and then press C on your
keyboard. This will create a comment around those nodes, and you will be able to insert a
description, as shown in the following screenshot:

94
Comments

Alternatively, you can create a node as if it was a node from the node menu with a right
click. This will add a comment without any node in it.
Comments are useful because if you move them, all of the nodes within it will move
accordingly (at least by using the default setting; you can change this, though).
Comments are also great at keeping portions of code together. If this portion is very big,
you may consider putting it within a function (if this improves readability, which depends
on the specific chunk of code and sometimes personal taste).

95
Comments
Comments can have other properties, including the possibility to change color. This is
another very useful tool when it comes to making a blueprint readable. In fact, you can
color-code portions of blueprint code. How you change its color? Select a comment and
in the details panel, you will be able to change its color, along with its other settings as
shown in the image below.

96
Blueprint interfaces for interactable objects
Blueprint interfaces for interactable objects
Now, it's time to learn about interfaces. I'm not talking about graphical interfaces, such as
GUI, HUD, and so on, but rather of a feature of many programming languages, including
Blueprint.
In particular, an object that implements an interface is guaranteed to have certain
functions. We learned a little bit about inheritance when we created a class based of the
type actor, since this Blueprint has all the properties of the parent.
Let's take the following structure as an example. We have an Actor class that holds some properties (as we have seen so far). We create two
kinds of Blueprint that both extend from Actor; one is an Animal, and the other one is a Vehicle. Both hold properties that are relative to their
field. In the case of the Vehicle, we might have functions relative to how the player can drive the vehicles, whereas an animal might contain
properties about where they live and so on. We further expand these classes by specializing them even more. We can
have Mammals and Birds that both extend Animal; whereas Car and Plane both extend Vehicle:

Now, suppose we have some cool functions that take a flying actor as input and
determines something (for example, the current altitude). We cannot pass an Actor, since
not all the actors fly, and on the other hand we cannot create a different function for each
flying actor we have in our scene. As a result, we can create an interface. For instance,
we can create the Flying interface, which is going to be implemented by both Bird and
Plane. As a result, our cool function that takes in a flying thing as input can take a Flying
object, which can be any object that implements the Flying interface. In this sense, the
function doesn't need to know whether that is a Bird or a Plane; rather, it knows that
whatever it is, it flies. And this should be enough to perform the calculation of the
altitude.

97
Blueprint interfaces for interactable objects
How does all of this come into play when we want to program games? The reason for this
is to create more quality code, which can be easily understood and used. So, in our case,
let's suppose we want the player to open a door, and there is a switch. Let's say that the
player presses the E button to interact with the switch, and the switch flips to open the
door. That's wonderful, but what if we have another kind of interaction? Let's say we
have a pickup object and when the player is near it, the player presses the E button again.
If we don't use interfaces, we need to create different pieces of code in our Player class
for each interactable object we might encounter. Instead, we create an Interactable
Interface, so that the Player class just needs to know that we are dealing with an
interactable object, without caring about which object is the specific object. Once we call
the interaction on that object, it will be the object itself to contain the specific code to
handle the interaction.
All of this will become clearer once we create the interface and see how it plays inside
our project. And that's exactly what we are going to do. In particular, we will implement
such an Interactable Interface on the Moving Platform of the previous chapter.

98
 Creating the Blueprint interface
Creating the Blueprint interface
Let's head back to our project and create a new folder to keep all our interfaces in one
place:
1. Name the folder Interfaces, or whatever names suit your project best:

2. Right-click inside the Interfaces folder, and instead of selecting the Blueprint Class, navigate down the
menu until you reach Blueprint | Blueprint Interface:

3. In this case, a dialogue window will not appear to ask you to fill up some data regarding the Interface,
but rather Unreal will create the interface for you directly. We will name it InteractableInterface:

4. Double-click on the interface to open the Blueprint editor for interfaces:


99
 Creating the Blueprint interface

100
 Creating the Blueprint interface
It's very simple compared to the full Blueprint editor since we are able to add a
function signature (with the term signature, I mean the input and the output of a
function, along with the name of the function). The graph that appears is not
editable—it will just give you a graphical look about what the different functions of
the interface will look like once implemented.
5. Let's select the default function from the panel on the right, which should be named NewFunction_0.
With just one click, you can rename it. So, let's name this function Interact.

6. Once selected, in the detail panel just below, we can change the signature of this function, in particular
by adding inputs and outputs:

7. We don't really need any input – we know that it is an interactable object and that we
just want to call the Interact function on top of it. The same goes for outputs, but for
keeping our project tidy and maybe extendable later on (also to learn how to handle
outputs), let's create an output, which will be a Boolean that tells us whether the
interaction was successful or not. Click on the plus sign next to the outputs, and
change the name to Success of type Boolean, as shown in the following screenshot:

101
 Creating the Blueprint interface

8. This is what the graph should look like, hinting at us that the implementation of the function will have a
return of type Boolean:

9. Save the interface from the top menu. We are now ready to use it for handling the interaction between
the player and the platform.

102
Implementing interfaces on Actors
Implementing interfaces on Actors
Now that we have created our interface, we need to implement it in some objects, after
which they will become Interactable.
Let's modify the platform we created in the previous chapter so that we can make it
intractable. In this sense, the platform will not be triggered when the player collides with
it, but rather when it has been activated:
1. Let's duplicate the platform we have with Ctrl + W (or right-click and select Duplicate). Rename it
to BP_InteractableMovingPlatform. Now, double-click on it to open the blueprint editor. To
make this class implement an interface, we need to change the class settings. You can access the class
settings from the top menu by selecting Class Settings, as shown in the following screenshot:

2. Once pressed, the button will light up, and you will have access to all the class settings from the detail
panel on the side. As you can see, here, we can set the direct parent of the class, which for now is Actor
(since we selected this as the base class for our platform in the previous chapter). Among other settings,
we have a section named Interfaces, in which we can implement one or more interfaces, as highlighted
in the following screenshot:

103
Implementing interfaces on Actors

3. By clicking on the Add button, you will be able to select among all the interfaces in your project. As
you can see, there's already quite a lot, since many are default interfaces within the Gameplay
104
Implementing interfaces on Actors
Framework of Unreal, along with any interfaces you might have created in your project:

105
Implementing interfaces on Actors

4. So, let's just type Interactable, since it is our interface, and the one we want to implement:

106
Implementing interfaces on Actors

5. Here's what it looks like once it's been selected:

6. We can see here on the right-hand side of our MyBlueprint panel that we have a new section named
Interfaces, and within it, we have our Interact function:

7. If we double-click on it, we will see the default implementation of the function, which at this current
stage will just return false (this is good as the default state since no interaction has been handled yet):

107
Implementing interfaces on Actors

In programming languages, if an object implements an interface, then all of those


functions need to be implemented as well. However, in Blueprint, this is handled
internally, thus even if you do not reach the end node with your implementation,
Blueprint won't throw any error at compilation time. As a good practice, be sure that the
end node is always reached by some path in the implementation of the interface function.

8. Now, to handle the interaction, we want to create an event so that whenever we have an interaction with
the platform, we call that event to trigger the movement of the platform. So, let's get back to the main
graph of the blueprint (by double-clicking on EventGraph on the side), and somewhere right-click | Add
Custom Event:

108
Implementing interfaces on Actors

9. We can name this event Move :

10. Now, let's go back to the Interact implementation, and between the interact node and its return, we are
going to insert a call to the Move event. So, right-click, add the call to the Move event/node, and
connect it, as shown in the following screenshot. Moreover, we want the interaction with the platform to
always succeed, so we are going to set our Success Boolean to true. This is the end result:

109
Implementing interfaces on Actors

11. Now, the implementation of the interface is ready, but there is no functionality in the Move event that
triggers the platform to move.

110
Moving the platform from the custom event
Moving the platform from the custom event
In our platform, we now have our Move event, and we want to connect to the rest of the
functionalities of the platform. In this case, it's simple. Whenever this event is called, we
want to do the exact same thing we would have done if the player had entered our
collider. Hence, let's remove our OnOverlapBegin event and plug in the Move event
instead. Since the interaction will start from the player, we don't need to check for the
player, so we can get rid of the cast as well.
Hence, plug the Move event directly into the Timeline node, as shown in the following
screenshot:

In case you have implemented a way to make the platform come back, here is a simple
solution, but we still trigger it from the custom Move event. We are going to use the
Reverse input of the Timeline to reverse the motion of the platform. Also, we are going
to use a FlipFlop. It's a special Blueprint control node that allows for switching between
two paths every time it is triggered. This is what the node looks like:

111
Moving the platform from the custom event

Hence, we can plug the Move event into the FlipFlop. As a result, every time the Move
event is triggered, the FlipFlop will alternate between the A path and B path, one moving
the platform forward and the other one moving the platform backward. So, path A is
connected to the Play input of the timeline, whereas the B path is connected to the
Reverse one, as shown in the following screenshot:

This concludes the interaction with the platform, but now we want to be able to start an
interaction from the player.

112
Binding keys in the settings
Binding keys in the settings
The next step is to decide which button is going to be the interactable button for our
player. In this case, I'm going to use the E key.
As a result, we need to bind this new key to a particular event, and we can do this by
going into the project settings, in the top menu, as shown in the following screenshot:

From the lateral menu, open the Input tab (you might need to scroll down a bit to find it),
as shown in the following screenshot:

113
Binding keys in the settings

114
Binding keys in the settings
Here, we are able to bind some user inputs to events in the game. In particular, we want a
button to be pressed (and in particular, E), and so we need to modify the action mapping,
as highlighted in the following screenshot:

The next step is to press the + button so that we can add an additional mapping. We can
name it Interact and bind it to the keyboard event of pressing E (through a drop-down
menu), as shown in the following screenshot:

This ends our little adventure in the settings since now everything is set and ready to go
for the last bit of our code to work. Now, we need to modify the character Blueprint.

115
Player interaction with Interactable objects
Player interaction with Interactable objects
We need to set a plan on how this is going to work. Normally, in a first-person game, you
would have a ray from the player's camera to check for interaction. Doing it in a third-
person game might be a little more complicated, and so for simplicity's sake, we are going
to assume that at any given time there might be only one interactable object around the
player, thus using collisions (with the capsule of the player) to detect when the player is
near an interactable object.
This sounds good, but we need to implement it. Follow these steps to do so:
1. Let's open our player Blueprint, which you can find under Content | ThirdPersonBP | Blueprints. The
file for this is called ThirdPersonCharacter:

2. Double-click the file to open it. This is the implementation of the graph. As we can see, we have many
nodes and events. Let's navigate into an empty space and add our code.
3. From the Components menu, drag the CapsuleComponent into the graph. We get all the overlapping
actors with that component. We are given back an array. With the get node, we can get an element based
on its index, and as the index, we can give the last one. This one will ensure that we are going to get the
latest actor that has started an overlap with the capsule component. This is what the code should look
like so far:

4. Now that we have the overlapping component, we should check whether it implements the Interactable
interface and call the Interact function on it. So, let's use the Does Implement Interface node to check if

116
Player interaction with Interactable objects
it implements the right interface (be sure to select the interface in the parameter down below in the
node). Then, we need to plug the result into a branch node, and if the condition is true, we call the
Interact message. If we right-click this, we can add the key event we created in the project settings by
typing Interact. Connect this node into the branch one. This is what the second part of the code should
look like:

5. If you are still having difficulties, this is the complete code:

6. Compile and save the blueprint. Once you're back in the main interface, place an InteractablePlatform in
the environment (don't forget to position the endpoint of the platform, otherwise it will not move), and
hit play. With your character, jump on it and press E. As a result, you will see the platform moving. If
you press E again, the platform will come back.

117
Extending upon what you've learned here
Extending upon what you've learned here
If you want to push what you have learned in this chapter a little further, try completing
the following exercises:
Think about other examples of interfaces and try to draw them out and identify their characteristics. For
example, create a diagram with only vehicles (for example, car, motorcycle, truck, military vehicles,
and so on). You'll be surprised about how many similarities as well as differences they have.
Look at your code and see what you might be able to turn into a function. Also, think about what
parameters you could make modifiable from only within the Blueprint and which ones you could make
modifiable from within the editor.
Try to create your own version of interaction. Can you think of any other interaction with the materials
we created in Chapter 1, Getting Unreal?
As a challenge, why you don't try to create a door that opens and closes (using the Timeline node,
similar to what we did in Chapter 2, Understanding the Basics Blueprints)? Then, create a switch that
is intractable so that when the player interacts with the switch, the door changes its state (for example,
from closed to open).

118
Summary
Summary
Ta da! Just like that, you've reached the end of this chapter! Let's take a moment to
reflect on what we have achieved and look forward to what is beyond. In this chapter, we
have seen what Blueprint functions are, how and when to use them, and why they are
great! Then, we learned about the ways to maintain effective Blueprints in the sense that
they are easy to read, kept nice and compact, and are understandable (this is super
important for teamwork), along with the concept of rerouting nodes. Lastly, we took a
dive into the world of interfaces, and learned how to create and implement them.
In Chapter 4, Adding UI Elements, we will learn about the basics of what UI/HUD/GUIs
are and their importance in game design and overall game experience. We will learn how
to implement UI/HUD/GUI elements within our UE4 project building. Lastly, we will
learn how to connect those user interface elements to gameplay (for example, the health
bar diminishes if the player collides with an object). So, cross over to the next page and
let's get going!

119
Adding UI Elements
Adding UI Elements
Welcome to the other side of interfaces. This chapter is jam-packed with a whole bunch
of awesome examples on how to use and implement UI within your levels. We will cover
quite a few examples within this chapter, but I am sure that you will find something that
will be more than useful in the later stages of the projects in this book or in some of your
own. In brief, this chapter will cover the type of interfaces that people will usually think
of—that is, the graphical interfaces that we have come to love (or hate) in games and the
ways that they convey different information. Often, we don't come to realize how
important UI is within a game and how it impacts our immersion within a game's
experience. In this chapter, we will cover the following topics:
The differences between different types of interfaces—UI, GUI, and HUD
What it is and how to use the Unreal Motion Graphics UI Designer (UMG)
How to implement different types of UI elements within our game
How to implement various HUD/GUI elements

As you can see, this chapter will go through all the important elements that you need to
know about (graphical) interfaces within Unreal Engine, from what they are to how
Unreal handles them. Lastly, we'll look at how to connect everything up so that we have
full functional interfaces, which we will most certainly extend upon in later chapters. So,
let's get learning.

120
Differences between UI, GUI, and HUD
Differences between UI, GUI, and HUD
In Chapter 3, Improving Interaction, we learned that an interface has, well…many faces.
In other words, it can be used in a range of different situations and can communicate
different things. We learned that an interface deals with describing characteristics of
certain things (remember vehicles and animals?). With this being said, it is important to
know what these different types of interfaces are in more detail. For example, some
interfaces can be interacted with, others only display information, and then there are
those that fall in the middle. So, let's learn about their differences and create some.

121
UI – user interface
UI – user interface
A user interface is a system by which people interact with a machine (for example, a
computer, mobile device, and so on). Typically, when we think of UIs, we think of
menus, buttons, and icons. However, a UI can also be textual such as the BIOS or typed
Command-Line Interfaces (CLIs) like the Command Prompt to represent different
components that are available to a player.
Typically speaking, there are four types of UIs:
1. Non-Diegetic: What you would usually think of when it comes to a UI in terms of a graphical overlay is
that they are only visible to the player, for example, menus, GUIs, and HUDs. These are the types of UI
that you are more likely to be familiar with and interact with in general when you play games. A simple
example is a game menu or the crosshairs of a gun.
2. Diegetic: These are immersive interfaces that are a part of the game environment—that is, they can be
seen, heard, and interacted with by players. It is a part of the game's fiction, of the game's world. For
example, it could be something as simple as looking at your watch to determine the level of radiation
present (Metro 2033). Think of these as immersive UIs in the sense that they are within the game, so you
would experience them as a connected part of the experience rather than as an external or isolated one
in comparison to non-diegetic.
3. Spatial: These are presented in the game's 3D space—it sits within the game's geometry. For example, a
navigational line leading the player to the next objective or text and arrows (often within a tutorial
level) indicating where to be or what to do (for example, take cover, shoot from position x, and so on).
4. Meta: These are abstract representations of in-game events that may or may not be communicated via
the environment. For example, a blood splatter on the screen after a player is wounded or a cracked
windshield screen if a player crashes a vehicle.

122
GUI – game user interface
GUI – game user interface
GUIs refer to an interactive interface within a game environment and can be considered
as a subset of UIs, but this is not synonymous. You might ask, why? The answer lies in
graphical. A GUI offers icons (rank, guild) and visual indicators (health, mana, money)
as opposed to text-based interfaces and navigation.
All GUIs are UIs, but not all UIs are GUIs. It is also likely that the terms are used
interchangeably during development, so keep this in mind!

123
HUD – heads up display
HUD – heads up display
The HUD displays real-time information to the player during gameplay, but this is
generally static in the sense that players cannot interact with it.
As we mentioned before, there are four main types of UI, along with HUDs and GUIs, so
what kind of chapter would this be if we didn't at least show you how to make them, even
in a basic way so that you can then extend them in the other projects within this book?
Exactly—so let's learn how to create a basic example of each.

124
Unreal Motion Graphics UI Designer (UMG)
Unreal Motion Graphics UI Designer (UMG)
So, how do we create an interface in Unreal? Thankfully, UE4 has Unreal Motion
Graphics—UMG. Now, what is an UMG? Well, it is a visual UI authoring tool in Unreal
that can be used to create UI elements from menus to HUDs and everything in-between.
Now that we have had some time to learn about the different types of UIs, let's have a go
at creating some of them within our game. Of course, in this chapter, I am just explaining
them all to you so that you can get an idea about how they work. That way, later, you can
decide for yourself which ones are suitable for your own projects or which ones you
might want to add to your project within this book. In any case, I leave you in charge of
the proverbial design steering wheel, so consider me as a guide until you're ready to go at
it on your own.
Within this chapter and, well, the rest of the book, really, we're going to create four
different types of UI. Now, you may be thinking, there are different types of UI? Some
may even argue that there is no such thing, but in either case, whether you're a believer
or not, we're going to discuss UI in terms of these four types to better illustrate their look
and purposes within games.

125
Non-diegetic (menu two ways)
Non-diegetic (menu two ways)
Let's add some HUD/GUI elements to our game. To begin, we will add a simple pause
menu that will allow us to pause the game. While this may seem simple at first, it's an
essential feature to any game.
Who doesn't like a menu with options, let alone options to create a menu? Here, we will
create two very simple menus. One will be a simple menu that is triggered by a single
key, while the other will require that the player clicks the resume or quit button to
interact with the game. Generally speaking, pause menus will have a resume button,
options, quit, save/load, restart, and so on. Many of these features will depend on the
type of game that you're creating.
To begin, select Add New | User Interface | Widget Blueprint and call this new
blueprint BP_PauseMenu.
What is a Widget? Well, we can think of a Widget as a user interface that allows us to
share a variety of things on the player's screen such as buttons, graphics, text, and sliders.
For our first menu, we will create something simple that is opened and closed by simply
pushing the P key to pause/un-pause gameplay:
1. Head over to the Palette Panel, select Text, and drag it down into Canvas Panel (to parent it).
2. Once you have done this, change the text to Pause Menu (or to whatever you wish to call your pause
menu, such as Game Paused) and adjust the size of the text in the Font section.
3. For this example, the Font Size that's used is 144.
4. Now, we need to anchor it. To do this, drag the flowery looking icon at the top left toward the middle
of the text. What we have just done is made sure that the text always remains at the center within the
screen, regardless of resolution. In this way, instead of the text appearing in the wrong position, we
anchor it to one. How does it do this? Well, the anchor's position is based on its height and width
percentage. You can see an example of this in the following screenshot, where the anchor points are
highlighted:

126
Non-diegetic (menu two ways)

Now, if you want to, you can either leave the menu as it is so that it will be
activated/deactivated each time you press a key—in our case, that will be P. Otherwise,
if you want to add a few more options that the player can interact with (resume or quit),
follow these steps to add them in:
1. From the Palette Panel (on the top left-hand side panel), create two buttons, one titled ResumeButton
and the other titled QuitButton
2. Now, also from the Palette Panel, add another two Texts to the Canvas Panel and call one Resume and
the other Quit
3. Make each of these texts a child of their respective buttons

Once you've done this, you will have a Pause Menu that looks something like the
following screenshot:

127
Non-diegetic (menu two ways)

Now, close the Widget Window and open Level Blueprints (Blueprints | Open Level
Blueprint).

128
Adding interaction for a key that's pressed (P) – Pause Menu
Adding interaction for a key that's pressed (P) – Pause
Menu
Next is the part where we will begin to add functionality to our Pause Menu:
1. To begin, right-click to bring up the Blueprint menu and add Event BeginPlay.
2. Then, drag from the output node on Event BeginPlay and select Create Widget.
3. Within Create Widget, go to Class and select BP_PauseMenu. Notice here that the name of the Widget
changes to Create BP Pause Menu Widget.
4. Now, we need to add a Player to be able to interact with the menu. To do this, right-click and type Get
Player Controller.
5. Drag the output pin from Get Player Controller and connect it to the Owning Player pin in the Create BP
Pause Menu Widget. Don't worry about the Player Index number because it specifies the number of the
player that interacts with it. This we will be used later in this book.

Now, we need to allow the menu to appear.


6. Drag the Return Value pin from Create BP Pause Menu Widget and type in Add to Viewport.
7. Click Compile and Save, and then close the Level Blueprint Window.
8. At this point, your Blueprint should look as follows:

With the first part of the level blueprint finished, we need to head back to the Widget
Window.
9. So, in the Content Browser, double-click on our BP_PauseMenu Widget. This time, though, in the top
right corner, click on Graph. This will open up the Graph Editor for our Widget.
129
Adding interaction for a key that's pressed (P) – Pause Menu
10. Now, in the Event Construct pin, drag the output and type Set Visibility.
11. Then, change the Is Visibility setting to Hidden.

It should now look like this:

To keep our project tidy, let's create another map for when the game needs to be paused.
Remember when we set the Interact input event in the project settings and that the map
was with the E key? Now, we need to repeat the same process, but this time we have the
TriggerPauseMenu input event instead, and it will be connected to the P key. If you are
having difficulties, refer back to the previous chapter on how to add an additional input
(we did it for the Interact one).
Once you have had done this, it should appear in the project settings:

130
Adding interaction for a key that's pressed (P) – Pause Menu

Now, head on over back to our Level Blueprints window again. Here, we need to make it
possible for the player to trigger the Pause Menu. For this example, we will do it when
the player presses the P Key.
12. Right-click and type in the TriggerPauseMenu input event, and place it in the graph.
13. Then, from the P pin, drag the Pressed pin and select Branch.
14. As a condition of the branch, we can use the Is Game Paused Node. As a result, now we know whether
the game is already paused when the player presses the P key.
15. If it is true, when we set the visibility of the Widget to Hidden, unpause the game, and set the visibility
of the cursor to false. In this way, we don't have the cursor of the mouse shown anymore. To set the
visibility of the cursor, there is a variable inside the player controller that we need to retrieve. (If you
are unsure, check the following finished graph.)
16. If it is false (the game is not paused), we need to do the reverse. Set the visibility of the Widget to
Visible, pause the game, and set the visibility of the cursor to true.

By the end of all this, you should have something that looks like so:

131
Adding interaction for a key that's pressed (P) – Pause Menu

132
Adding interaction with menu buttons (Resume and Quit)
Adding interaction with menu buttons (Resume and
Quit)
If you're doing this from scratch, you will need to follow points 1 to 16 from the previous
section otherwise, just continue from here:
1. Head to the BP_WidgetPausdemenu editor and click on the OnClicked event + picture.

2. For the Resume functionalities, we need to unpause the game, hide the pause menu, and finally, we need
to set the cursor to not visible anymore (as we did before) by using the player controller. Here is what
your final graph should look like:

3. For the Quit functionalities, this is very simple, since there is already a quit node. Just plug it into the
Quit Button event:

133
Adding interaction with menu buttons (Resume and Quit)

And that's it, now the pause menu works. Now, if you play in-game, it will look like this:

134
Pressing E to interact
Pressing E to interact
If you play a lot of exploratory type games, be it Guild Wars 2 to Tomb Raider, chances
are you've had an encounter where you have come close to an object and you need to
interact with it by pressing a key or button in some way. In this example, we're going to
do just that. Similar to our previous example, when you get close to an object (for
example, a door), you will see a nice little bit of UI show up that will prompt you to
interact with it by using the I key and open sesame! You will be able to go through.
This will be a little more complicated because it's not just about UI since we will also
need to make the door rise, but we will draw on a few things from what we have already
done in this book to get it all done.
Now, we'll create the UI for the user to interact with the door to trigger it to open. If we
remember a little of what we did for the moving platform in Chapter 2, Understanding
the Basics of Blueprints, we created some colliders. We will need to do the same to
trigger our interaction UI:
1. To begin, let's create the door. Drag a cube into our scene and scale it to suit you. For our door, we will
use the following scale values: (X): 2.0, (Y): 0.25, and (Z): 2.75. We will also place it at the top of
stairs within the default third-person scene geometry, like in the following screenshot:

2. Then, select our newly created cube/door, and in the details panel next to Add Component, click on
135
Pressing E to interact
Blueprint Add/Script, which will transform this object into a blueprint.
3. Call it BP_TriggerDoor and click Create Blueprint.

If you have continued straight from Chapter 1, Getting Unreal, you will notice here that
we created the Blueprint trigger in a different way. The reason for this is no more than to
show you an alternative method. By following the same steps as in Chapter 1, Getting
Unreal, you will also end up with the same result. However, one inherent advantage in
doing this for UI is that it makes it easier to gauge the appropriate size and position of the
font. This will make more sense later.
4. Once inside the blueprint editor, we need to select the static mesh component and change its
movability to Movable, as shown in the following screenshot:

Now, in the Blueprint editor, we will add a trigger box in a similar fashion to how we did
for the moving platform. Then, we will add our UI text that will appear on-screen when
the player enters the trigger box.
5. Click on Add Component and type Box Collision. This will add a box in our Viewport.

6. Using the Details panel (or the controls in the Viewport), scale the collision box to surround the door,
like in the following screenshot:

136
Pressing E to interact
7. Click on Add Component and type Text Render. This will add some text into our Viewport. You may
need to rotate the text so that it appears in the right direction as your box collider, so adjust as needed.
8. Now, in the Details Panel, rename the Text to something that suits you. We will rename it like so: Press
E <br> to interact. Notice the <br>? This simply puts the text after it, on the following line, like in the
following screenshot:

Notice here that we can get a better idea about the size and position of the font given that
we have already scaled our box collider.
9. Then, we need to make the UI text invisible (by default, for triggered-based UIs). You can easily do this
by looking over in the Render section in the Details Panel and unticking Visible , like in the following
screenshot:

10. Now, go to the Event Graph.


11. Now, since our door is intractable, we are going to use the interface we created in Chapter
3, Improving Interaction. So, just like we did for the moving platform, we can add the interactable
interface to this blueprint.
12. Again, we are going to handle the interaction for opening the door in a similar way, but first, we would
like to make the UI appear when the player is inside our collision box.
13. Select the Box from the Components panel and (as we did back in Chapter 2, Understanding the Basics
of Blueprints, and Chapter 3, Improving Interaction) add the On Component Begin Overlap and On
Component End Overlap events by pressing the respective "+" buttons that are highlighted in the
following screenshot:

137
Pressing&#xA0;E to interact

14. In these two events, we would like to check whether it is the player that has entered the collision box. If
so, we want to trigger the visibility of the Text Render, based on whether the player is entering or
leaving. It's easy to make it, but if you have difficulties, just check the following graph:

17. Then, we can implement the interaction to open the door. At this stage, you should be able to do this by
yourself, especially by following similar steps to what we used for the moving platform in the previous
chapter. Thus, I would suggest trying it yourself before reading the solution that follows.
18. To move the door, we need to store the initial location (in World Space) of the static mesh component
that represents the door. So, in the BeginPlay event, we just assign this value to a new variable of type
Vector, which we can name StartingLocation, as shown in the following graph:

138
Pressing&#xA0;E to interact

17. Next, we need to create the logic that opens the door. Create a new Custom event and name it
OpenDoor.
18. Then, we can create a timeline (as we did back in Chapter 2, Understanding the Basics of Blueprints)
and connect it after the Create Door event.
19. Inside the timeline node (so that the curve editor appears when you double-click on the timeline node),
create a curve (tracking a float) that starts at (0,0) and ends at (3,250). This means that the door will
move 250 units in 3 seconds. This is the image of the curve:

139
Pressing&#xA0;E to interact
20. From the Update pin of the Timeline node, we change the position of the door (in World Space). In
particular, we take the starting location and we add a new vector in which the only non-zero component
is z, which gets out from the Timeline node, as shown in the following graph:

21. Finally, let's modify the Interact function (that was added when we included the interface), and as we
did for the moving platform in the previous chapter, we trigger our OpenDoor event, and we report
success:

22. Then, run the game and when the player collides with the trigger box, you should see something like the
following screenshot:

140
Pressing&#xA0;E to interact

23. Then, when you press the E key, the door will open, as follows:

Now, while this feels like it requires a lot of work in the beginning, it is one of the most
fundamental things to learn about, regardless of what type of game you are creating.
Therefore, we will be reusing what we have done here many more times later in this
book.

141
Spatial
Spatial
Which way do we go? That's probably one of the most asked questions in a game when
you're stuck in a level. So, let's help a poor player out with some basic navigational
arrows. Now, just to be clear before we begin, these will not be tracing a path or anything
like that. These types of spatial UI are a little bit more complicated than the space that we
have here, but we will discuss them in later chapters when we create our second project.

142
Meta
Meta
Let's have it so that every time the player runs into an enemy cube, they get a strange
effect on the screen. This is something similar to a player getting shot and blood
appearing on the screen or when you're playing a racing game and you drive through a
puddle, and your car windscreen gets covered in mud. We will be covering this later in
this book when we create our third project.

143
Extending upon what you've learned here
Extending upon what you've learned here
Now that we've covered a lot of stuff about UIs, how about pushing the extent of your
knowledge a little bit further?
Think about some games that you have played—is there anything that you would change about the UI?
Using what you have learned in this chapter, try to replicate a UI from a game that you like.
Try extending upon what you have learned in this chapter by adding some of your own UI elements. Try
creating some in Photoshop or finding some that are available on online stores. Import and connect them
within the game.
See if you can trigger the meta UI element by doing another activity such as walking into a wall.
Make the door come back down after a certain period of time has passed.
Change the input that's used for enabling an event.
Next time you're playing games, see if you can identify the type of UI that you're seeing (for example,
diegetic, spatial, and so on).

144
Summary
Summary
We've reached the end of this chapter, but it's really just the start of a new beginning as
we move into our penultimate chapter for this project—Chapter 5, Adding an Inventory.
But for now, let's focus on what we have achieved in this chapter. To begin, we have
learned about the different types of graphical interfaces. We have learned how they are
created within Unreal using the Unreal Motion Graphics UI Designer. We have gone
through the necessary steps to create essential UI elements that will not only be useful for
our first project but the others throughout the rest of this book. Even though they are
basic actions, for now, you have gained the necessary foundation that you will extend
upon in later chapters.
Now, as we head toward Chapter 5, Adding an Inventory, we will learn how to create
and implement an inventory system within our game. To add items into our inventory, we
will create various pickups that we can add and use within our project, all of which will
be connected to our inventory system. They will also be represented within the game's
HUD. So, let's get going!

145
Adding an Inventory
Adding an Inventory
What is the point of having—let alone collecting—items in a game if you don't have an
inventory? Seems pretty obvious, right? That is why we're going to create an inventory
that you can not only use with this project but will also be able to use with the other two
projects within this book. Traditionally, in games, an inventory is a way to store items
that you collect during gameplay. In most cases, you can access it via the UI/HUD at any
point during the game. In other cases, you can only access them from various locations,
such as within a chest or via a trader. However, one thing that should be considered is
that an inventory is different from, say, storing bullets or guns. An inventory is an explicit
feature within the game that stores multiple (different) items (also with a limit) for use
later. In this chapter, we will do the following:
Learn about the use of inventories in games
We will learn how to create a basic inventory using Blueprints
Next, we'll cover how to create items that can be collected by the player
Then, we'll learn how to add those collected items to the inventory
Lastly, we'll learn how to connect HUD/GUI elements to gameplay

So, let's get collecting!

146
Picking up and collecting items
Picking up and collecting items
Now, to have a successful inventory, you need some stuff to fill it up with. Because of
this, we will create some basic but very common collectibles:
Health (red sphere)
Potion (purple sphere)
Gold (yellow sphere)
Special Orb (white sphere)

Of course, you can use 3D models of your own, but we will cover that in the next chapter
when we import an asset package from the Unreal Marketplace. The following is an
example of the very simple graphics that we will be using for our inventory:

147
Creating an inventory
Creating an inventory
We need to create the actual space that will be our inventory, both in a visual and in a
technical sense. To do this, we will need to add some UI elements, like we did in the
previous chapters.
Let's begin by following these steps:
1. Add a new subfolder within the Interfaces folder to keep all of our Inventory assets organized. Call it
something that is useful. In this case, we will call it Inventory—no surprises there!
2. Now, create two new Blueprint User Interface Widgets (right-click in the content browser and
choose User Interface | Blueprint Widget).
3. Call one Inventory and the other InventorySpace.
4. Open the Inventory UI widget.
5. First, search for and add a Vertical Box.
6. Then, add some text so that we have a title for our Inventory. The text can be something as simple as
Inventory or Your Inventory, and so on. Feel free to align it as you want (center, left, and so on), but
make the box surrounding the text fit the size of the text.
7. Now, make sure that the text is a child of Vertical Box.
8. Then (as a child), search and add Uniform Grid Panel. The reason that we are using a Uniform Grid
Panel is that, for now, all the icons are the same size, so it's just a matter of organizing them in a nice
and structured way, because who doesn't love a nice, organized inventory?

9. Now, we need to decide on how big to make it in terms of how many rows and columns will we need.
Since we only have four inventory items, we'll just have two rows of two. Of course, if you have
more/less, you can change this. You can also just keep the inventory to one row of four. At the end of the
day, it will depend on what type of items you're using and how they need to be used. For example, if
you're planning on having the character use items during gameplay (for example, potions, health, and so
on), you will allow them to create combinations for items (for example, super potions, explosive
weapons, and so on). Therefore, a single row may be more practical than a two by ten grid setup.
10. Now, in the Details Panel, set it to Fill. By doing this, it will automatically fill the grid to the size of the
Vertical Box. Once you have done this, it should look like what's shown in the following screenshot:

148
Creating an inventory

11. Save and close the editor window.

Now, at this point, we're going to be adding a few things (spaces) so that we can have
items within our inventory. We will need to open the InventorySpace UI Widget:
1. First thing's first: delete the Canvas Layer.
2. Then, search and add Button and call it InventoryItemBtn.
3. Next, search and add Image and call it InventoryItemImg.

4. Now, with the Image component selected, head over to the Details Panel and select both Vertically and
Horizontally Alignment Fill. An example of this can be seen in the following screenshot:

149
Creating an inventory
5. Save and then close.

Now, we need to head back over to the Inventory UI Blueprint and begin building our
inventory. Within the Blueprint, we need to perform the following steps:
1. Search and add InventorySpace as a child to Uniform Grid Panel. We will need to add it four times
since we will have four different inventory items (potion, health, gold, and special sphere).

A really important thing to remember here is to not copy and paste the Inventory Item
instances within the Hierarchy. Always drag a new instance from the Palette. Otherwise,
you are likely to get compiler errors.
2. Name each instance of inventory space with a meaningful name. We will use InventorySpaceItem# here.
For example, InventorySpaceItem1.
3. Now, we need to position them within the inventory. To do this, click on InventorySpaceItem1 and in
the details Panel, change the value in both the Row and Column. Remember here that numbering starts at
0. So, InventorySpaceItem1 will have a row and column value of 0, InventorySpaceItem2 will have a
row value of 0 and a column value of 1, and so on.
4. Next, select the Uniform Grid Panel and change the Slot Padding to something more desirable. For this
instance, we will use the value of 2.0.

5. Then, select the Vertical Box and resize it appropriately. You should have something that looks as
follows:

150
Making the Inventory appear and&#xA0;disappear
Making the Inventory appear and disappear
Like we have done already for both the Interact key binding and Pause, we need to add a
binding for the Inventory. So, head to Project Settings and go in the Input section. Here,
press the plus to add an additional Action Mapping. Let's call it TriggerInventory, with a
binding of the key to the letter I:

Open the Third Person Character blueprint and navigate to an empty section of the graph.
Here, we will add the TriggerInventory mapping (for now and as the default is I), then
everything that it connected to this node will follow. With that said, let's move on to
actually triggering it during gameplay.
To do this, you will need to follow these steps:
1. Open the Third Person Character blueprint.
2. Right-click, type, and select TriggerInventory (Input | Action Events | TriggerInventory).
3. Now, drag the pressed pin from InputAction TriggerInventory and type/select FlipFlop (Flow Control |
Switch | FlipFlop).
4. Then, drag the A pin from FlipFlop, type/select Create Widget (User Interface | Create Widget), and set
the class to Inventory.
5. Then, drag the B pin from FlipFlop and type/select Remove from Parent (Widget | Remove from
Parent).
6. Right-click on the ReturnValue pin in Create Inventory Widget. Then, select Set to Variable and call the
Variable InventoryRef.
151
Making the Inventory appear and&#xA0;disappear
7. Now, in the My Blueprints Panel, under variables, drag the InventoryRef variable into the Event Graph
and connect it to the Target pin of Remove From Parent.
8. Now, drag this from the output pin of Create Inventory Widget.
9. Lastly, drag the output pin from SET and type/select Add to Viewport (User Interface | Viewport | Add
to Viewport), and then connect the connect the return value pin in SET (blue) to the target pin in Add to
Viewport. Once you have done all this, it should look like what's shown in the following screenshot.
10. Now, click compile to make sure there are no errors. Then, save and close the Event Graph:

With this done, it's time to test it in-game. If you have successfully followed the steps so
far, when you press the I key on the keyboard, you will see your inventory, and it should
look something like the following:

152
Making the Inventory appear and&#xA0;disappear

But we are far from done. Now, we need to make the inventory a lot more meaningful.
Let's start by improving what we have done so far. In fact, we need a persistent
inventory, meaning that we do not want to create (initiate) a new one every time the
player presses the I key. Therefore, let's move the creation of the inventory into the
Begin Play event, as shown in the following screenshot:

On the other hand, when the player presses the I key, we can toggle the visibility of the
153
Making the Inventory appear and&#xA0;disappear
inventory itself, always using our dear FlipFlop node. As a result, the final blueprint
should look like what's shown in the following screenshot. It is important to remember the
different settings for both the Set Visibility nodes—that is, one is set to Hidden and the
other is set to Visible:

Now, we need to create a structure for our inventory. To do this, we will need to set up a
few things:
Add a new folder to the Hierarchy (as a child of Content) titled Structures
Right-click, select Blueprints, and then select Structure and call it ItemStructure

Here, you can provide all the different characteristics that general items can have within
a game, such as whether it can be equipped by a player, if it is rare/common, and so on.
We will use this structure so that we can keep all the data of an item stored all together in
a nice package. We are going to add three variables, where two will only be used as an
example. This is because, for now, we will only be using the last variable, but I want to
show you here now since you might want to extend the inventory system at a later stage.
Therefore, by being exposed to this now, you will be familiar with it later:
1. We can begin by adding a new variable, calling it ItemActor, and setting its type to Actor.
154
Making the Inventory appear and&#xA0;disappear
2. Next, we will add another variable called ItemString and set its type to String.
3. Lastly, we will add another variable called ItemImage and set its type to Texture2D.
4. Once you have done all this, you will have something that looks as follows. Make sure to save it and
close the Structure window:

Now, what we need to do is give the inventory space the ability to process one of these
item structures to show the image contained within the structure. The way we are going
to pass information into the InventorySpace is by creating a variable with the type Item
Structure and then assign this variable every time we need the InventorySpace to show
the image. On the other hand, once the InventorySpace has the Item Structure, it binds
the image to show the image that is contained within the structure. Now, open
the InventorySpace Blueprint and navigate to the Graph Editor. Follow these steps:
1. Add a new variable called ItemStruct and set the variable type to Item Structure (the one that we just
created).
2. Set the variable to be public. To do this, just click the eye next to the variable so that it becomes open.
An example of this is shown in the following screenshot:

155
Making the Inventory appear and&#xA0;disappear

3. Next, we need to bind the image within the structure to get the image to display. So, let's go back to the
Designer Window and select InventoryItemImg.
4. In the Detail Panel, navigate to Appearance and select Bind | ItemStruct | Item Image, like in the
following screenshot:

156
Making the Inventory appear and&#xA0;disappear
As a result, every time we assign an item structure, the InventorySpace will display it.
Now, we need to understand how to assign an Item Structure to a specific
InventorySpace.
To do this, follow these steps:
1. Open the Inventory Blueprint and navigate to the Graph Editor.
2. Create a new variable, call it Items, and set its type to Item Structure.
3. We decide to store all the items that the players find in this class. However, our Items variable needs to
be an Array. To do this, simply select the icon next to the Variable Types and select the "grid" icon. An
example of this can be seen in the following screenshot:

Since this variable is going to be the actual variable for the player, we need to
provide a way to add and remove items from it. On top of this, we need to pass
down the right Item Structure to the single InventorySpace. Let's start by creating
two custom events in the Event Graph, one named AddItem and another
named RemoveItem, both having an Item Structure as an input (in the Details
Panel), like in the following screenshot:

157
Making the Inventory appear and&#xA0;disappear

4. Now, drag the Items variable into the Graph Editor.


5. Drag from the Items variable and search/add Add (Utilities | Array | Add) to the Event Graph.
6. Do the same again, except search/add Remove.
7. Next, drag the output pins from both the Custom Events (AddItem/RemoveItem) into their respective
nodes (Add/Remove).

8. Then, drag the blue pin in both the custom events into their respective blue pin in the Add/Remove
nodes. At this point, you should have something that looks as follows:

158
Making the Inventory appear and&#xA0;disappear

9. Next, we need an array with all the InventorySpace(s) that we have created, which in our case is just
four. You should be able to see them in the Variable Panel.
10. First, drag these Inventory Item variables into the Graph Editor.
11. Now, create a Make Array node.
12. Then, connect each of the Inventory Item variables to the Make Array node, just like in the following
screenshot:

159
Making the Inventory appear and&#xA0;disappear
13. Now, we need to create a ForEachLoop node (Utilities | Array | ForEachLoop). The logic is going to be
simple, but the graph will become a little bit messy with the number of connections that we will need to
create.
14. We loop for each of the InventorySpace(s) and assign one of the Item Structures until we have some of
them within our Inventory.
15. When we have finished them (the index of the ForEachLoop is greater than the length of the Items array),
we assign an empty structure to the InventorySpace.

Now, let's break down these steps:


1. To begin, plug the array we have created with all the Inventory Item inside the ForEachLoop.
2. From both the Add and Remove node, let's plug their output pins in the input of the ForEachLoop, as
shown in the following screenshot:

3. We can create and the check whether, in this iteration of the loop, we have finished the ItemStructure by
bringing the Items variable into the graph and dragging its pin into the Length node.

160
Making the Inventory appear and&#xA0;disappear
4. Create a < node.
5. Then, drag the Array Index pin from the ForEachLoop and connect it to the first pin of <.
6. Connect the output pin of Length and drag it to the second pin of <.
7. Finally, from the ForEachLoop body, we drag the pin to create a branch and plug the result of the <
node into the branch node. I know, it might sound confusing, but with the following screenshot in front of
you, this should be easier to understand:

8. One last effort is to assign the correct image structure to the InventorySpace in the loop, depending on
whether the branch is executing True or False.
9. Let's start by building the False branch since it is easier. Drag the ArrayElement from the ForEachLoop
and add the Set ItemStruct node (which is the variable we created before on the InventorySpace
blueprint). Now, from the SET node, backward, drag the Item Struct to create a Make Struct node (and
leave everything as default, empty). Once you have done all of this, this is what you should have so far:

161
Making the Inventory appear and&#xA0;disappear

10. Now, for the True branch, we again drag the ArrayElement from the ForEachLoop and add
the SET ItemStruct node. However, this time, instead to create an empty one, we take the Items variable
(we drag it into the graph), and from it create the GET (array) node, in which we plug the Array Index
of the ForEachLoop into it. Next, the result of the GET node goes inside the SET one. We have now
completed the most complicated blueprint of this chapter, which looks as follows:

Now, the whole system works, but we don't have any items to pick up. Therefore, we
162
Making the Inventory appear and&#xA0;disappear
need to create one more blueprint!

163
Collecting items
Collecting items
Now comes the part where we need to pick up items and add them to our inventory. As
you can see, we have four basic primitives (spheres) with simple materials attached to
them, like the ones that we created earlier in this book, with the exception of the potion
material (it utilizes Fresnel). You can find out more by opening the sample project or by
visiting the following link: https://docs.unrealengine.com/en-
us/Engine/Rendering/Materials/HowTo/Fresnel.
So, we need to create a blueprint that is able to implement all the pickup functionalities
and have the possibility to be customized into different items, like in the following
screenshot:

Create a sphere in the world (you should be able to do this by now), and once selected
click on Add Script from the Details Panel. As a result, this will "transfo""rm" our static
mesh into a Blueprint. Let's rename it BP_MasterItem (since it will be the base for each
item in our mini-game) and place it in an appropriate folder.
Double-click on it to open the Blueprint Editor:
1. Since this is a dynamic object, meaning that it could potentially change position (or in our case
disappear once the player picks it up), we need to change its mobility so that it's mobile. This will also
ensure that we have shadows rendered correctly since, in this case, they are generated at runtime.

2. Next, we want to define the properties of this object. In particular, all the items properties are contained
164
Collecting items
in the ItemStructure. As a result, we can add this blueprint as a new variable of type ItemStructure and
make it public (click on the eye next to the variable to make it open and yellow). We can name the
variable something like ItemProperities. This is what it should look like in the Details Panel (I've
changed the category as well so that I can find it easily):

3. Next, we need to provide the item with a collider and make it interactable. Like we did for the
Interactable door and Platform back in Chapter 4, Adding UI Elements, and Chapter 3, Improving
Interaction, and let's create a Box Collision and make it reasonably big around the object (for example,
a scale of 4 on all the axes). This is what it should look like in the Viewport:

165
Collecting items

4. Also, to make the object interactive (again, as we did for the door and platform), we need to implement
the interactable Interface. Once we add it, let's modify the Interact function.
5. Within this function, we need to make the player pick up the item (adding it to the inventory), and
destroy the item from the world. Remember that we have a reference variable of the inventory within
our ThirdPersonCharacter blueprint.
6. Let's take the player pawn (Get Player Pawn) and "cast" it into a ThirdPersonCharacter (Cast to
ThirdPersonCharacter).
7. From there, let's retrieve the InventoryRef variable.
8. With this inventory, we call the Add function, and we pass the ItemProperty variable as a parameter.
9. Next, from the Add function call, we drag another pin to destroy (DestroyActor) the object.
10. Lastly, we connect the return node.

As you can see here, we did everything in one go because the logic is simple, and now
you can follow along. The following is a reference of the completed interaction
implementation on what the graph should look like (but try and do this yourself first):

166
Collecting items

Now, we have completed the Pick-up system. The only thing left to do is test the system,
create some items, and see how everything works.
Let's drag some of the BP_Master items inside the game level. For each one of them, we
need to change the material and properly set the item parameters, in particular, the Item
Texture. So, once we pick up an item, it will be correctly shown in the inventory. The
following is an example of an object that I dragged into the level and changed in the
Details Panel (remember to change the material as well):

167
Collecting items

This is what it looks like in-game:

168
Collecting items

169
Extending upon what you've learned here
Extending upon what you've learned here
Now that we have an inventory, the possibilities are endless when it comes to allowing
the player to collect, use, and even discard items. Not only does it influence the type of
gameplay that your game provides, but it also has influence over the design of the overall
gameplay experience. Here are some suggestions about other ways that you can
challenge yourself with what you have learned in this chapter:
Like we did in the previous chapter, try adding some UI to the objects that say things like Potion or Pick
up Health, and so on when the player gets close to them.
Try modifying the UI a bit to change its aesthetics, or even try adding your own graphics. Push the
boundaries of what you've learned here and get creative!
Have a look at the project files and try modifying or creating your own version with different colors and
different Fresnel settings.
As you will see, the background for the inventory images is white (the default state when we created
them). Try to make them transparent. HINT: it is within the InventorySpace Blueprint Widget.
As we can see, our inventory has space for only four items. However, if the player collects the fifth
item, it is still added to the inventory. Write a check that if the player already has four items in the
inventory, a message will show up saying that the inventory is full.

Other ideas to extend the inventory might be done by implementing the following
functionality:
To Use : For the player to use an item, we need to be able to remove it from the inventory and then have
it interact with the game (for example, the player, another player, and the environment).
To Drop: For the player to be able to drop an unwanted item, we need to not only remove it from the
inventory, but also place it back within the game world (and that's why you might need a proper
reference in the Item Structure, but be careful if you destroy the object, as we did).
To Combine : For example, you can allow the player to combine the health and potion items together to
create a super health elixir that will restore the player's entire health.

170
Summary
Summary
Once again, we've reached the end of this chapter, but it's not the end. In the next
chapter, Chapter 6, Creating an Adventure, we'll conclude our first project, but two more
adventures await. So, let's take a moment to pause and reflect on what we have
accomplished in this chapter. To begin, we learned what an inventory is within a game
and how to create a very simple one of our own that allows us to collect and store
objects. This was quite an intense section that involved many steps but, in the end, we
now have the necessary foundation to build an awesome inventory. Of course, this won't
be the only time that we will use one—just about every game has an inventory, even if it
functions in a slightly different way, so bookmark this chapter!
In the next chapter, Chapter 6, Creating an Adventure, we will create a basic game
environment and combine all the things that we have learned from Chapter 1, Getting
Unreal, to Chapter 5, Adding an Inventory. We'll even extend upon what we have
learned thus far so that you can add a bit more magic to your game. We'll look at basic
level design when we create our first game environment. We will also create and
implement a basic quest system by using blueprints. So, let's battle the boss level that is
inside of the next chapter.

171
Creating an Adventure
Creating an Adventure
Welcome to Chapter 6, Creating an Adventure. This is our final chapter for our first
project within this book. Here, we're going to learn about the basics of level design. Think
of it as a crash course in getting an environment to the stage where it is playable and
represents and facilitates the type of gameplay that you want. Apart from covering basic
level design, we'll also cover the following topics to complete our first game:
Basic level design
Creating a game environment by using some project files that we have downloaded from the Unreal
Marketplace
Create a basic quest system using Blueprints

With this being said, this chapter should allow us to have a nice completed project with a
fundamental inventory, along with basic gameplay interaction, which we will be learning
about here and from the previous chapters, so let's begin by designing our level!
If you have a hard copy of this book and the pictures are B/W, you can find all of the
colored images on the site of the publisher. In fact, the environment in this chapter can be
better appreciated with colors. Check the front matter to find the link for where you can
download the colored pictures. Also, check the project files—you have the whole project
to play around with.

172
Basic level design
Basic level design
Here comes the chapter that you have been waiting for! We're going to be learning about
level design. Generally speaking, you could write an entire book about the development
of a game level. Depending on what your requirements are, the technical specifications,
the kind of atmosphere, gameplay, and the overall experience that you want the player to
engage in can vary based on how you approach level design. After completing this
chapter, you will have a great foundation to start with. So, let's begin.

173
Creating a game environment
Creating a game environment
Where do we begin? Creating a game environment isn't exactly an easy task, nor should it
be. It involves many different thought processes and has many different approaches, let
alone steps in order to properly create a believable, engaging, and enjoyable experience
for the player. There are many (entire) books out there that focus on level design, and so
it is not possible to condense the concept of level design within a single chapter! Also
because they each cover a different aspect and even genre. However, we'll cover
different, yet important parts of level design to ensure that you have a solid
understanding of the essential components of a solid game environment.

174
The objectives
The objectives
We will begin with a map and a list of objectives (what the player will need to do within
the level, and so on). This is important because it will also influence the gameplay and
how a player experiences the level. For our level, we'll have the following objectives:
Locate (and collect) four items
Interact with objects (unlock doors)
Navigate to different parts of the map

175
The map
The map
Now that we have an idea about what the player needs to do within the environment, we
need to create an environment that the player will explore to complete those objectives.
At this stage, we will create a basic plan to guide us during our level creation. Depending
on what assets you are using (if any), your map will likely look different. The map that
we will design here will have the use of the downloaded package in mind. Here is an
overview of the map that we will use for the design of our level:

176
The map

On the left is the completed map, while on the right is an example of how you would
sketch it out before designing it.

177
Blocking the level in
Blocking the level in
At this stage, you will want to begin blocking in the level. Here, we will focus first on the
navigational path, so it may resemble somewhat of a maze, but that is okay. Here, we will
playtest the environment a few times before we start adding more detailed assets so that
we can develop the atmosphere of the game. You want the level blocked out to the point
where the path(s) that the player takes to navigate around the level are the same, in that
they will take one after the level has been polished. Of course, this is not to say that the
navigation won't change—in most cases, it will. However, what I mean here is that you
have a sense of the movement within the game, regardless of whether it's inhibited by the
environment. A perfect example of this is when you create a new project within Unreal
and you have some basic plain (untextured) geometry, except with a blocked-in level, it
is a more detailed and intricate albeit blocky version of it—almost as if you created
everything out of Lego.

178
Adding in the (core) game assets
Adding in the (core) game assets
Once you have playtested your blocked-out level and everything feels about right in
terms of navigation, you will want to start adding the key items such as potions, enemies,
items, and so on. Here is where you want to see how the player moves within the
environment, along with the parts related to the quests, to ensure that they are in sync.
That is to say, we are checking that the navigational path between objective 1 and 2 of
the quest is too short, long, difficult, easy, and so on. Basically, you want to get a sense of
how the gameplay and flow feel overall and to make sure that it feels right and that it
doesn't become unbalanced.
Next, we want to begin by adding some objects to our level. If you've already some
made, that's awesome! You will be able to import them straight away. However, if you
don't, we are going to do this first before diving into Blueprints for two reasons:
So that we can get familiar with adding objects to our project's level.
So that we can have objects to add Blueprints to.

The following section will cover all that we need to know about adding assets from the
Marketplace into our project. If you want to use your own assets, please refer to the
official documentation by visiting the following link: https://docs.unrealengine.com/en-
us/Engine/Content/ImportingContent.

179
Importing assets from the Marketplace
Importing assets from the Marketplace
If you have the Unreal Editor open, save what you have done so far and close it. Now,
open the Epic Dashboard. On the side menu, click on Library and scroll down to where
it says Vault. Here, you will find a list of all the asset packs that you have currently
installed. To add to our project, simply click Add To Project, select the project, and click
Add To Project. Keep in mind that when we add the project files to our project, will
need to install them. Depending on your computer specifications, this may take a
variable amount of time, so patience is necessary. We can see this process outlined in the
following screenshot:

180
Importing assets from the Marketplace

181
Populating the level
Populating the level
Perfect—we now have our assets within our game's Content folder. Next comes the
creative part. We get to dress up our level with some actual assets from the downloaded
package. Here, you can replace the cubes that you have used to block out your level with
the real geometry. Obviously, this step would come a bit later if you were developing
your own assets, but it is equally important when you are creating your assets that you
test them within the environment as early as possible so that they can be iterated (it is a
completely normal part of the game design/development process). So, add the assets to
the environment as you prefer, keeping in mind that it has to make sense as well. For
example, if you have streets, there needs to be an end to them, not just a weird and
awkward opening to infinity land. You can see an example of this as follows:

Take time to experiment with your environment and be sure to play it as you design it. It
is quite easy to have a game that looks perfect from a top-down perspective or within the
editor's viewport, but when it comes to playing it, it can be a shock if you've scaled all
your trees and buildings too big or too small.

182
Populating the level
For the complete project for this chapter, which incorporates everything that we have
done so far, you can download the files here: www.player26.com.
In the following screenshot, you can see a preview of the level:

183
Creating a basic quest system
Creating a basic quest system
In our list from before, we created a list of aims that we want the player to achieve.
These will now become part of our quest system. A quest system is basically an in-game
list of objectives that the player must complete to progress to the next section of the
game. What we are going to do is create a basic quest system that will have some text on-
screen that will provide a list of things for the player to do. For now, we'll keep it simple,
such as locating objects or performing actions (for example, opening a door). Here is a list
of what we will be asking the player to do in order to complete their quest (not in any
particular order):
Open a door
Locate the four blue signs (see the following screenshot)
Reach the roof (Building 01)

Now, this should be a simple enough list to get us going, at least in terms of a basic quest
system. However, keep in mind that later within the other projects in this book, we will
be extending upon it all in greater detail by creating more complex quest systems:

The preceding screenshot is an example of one of the Blue Signs that players must locate
within the level.
In most games, a player will need to interact with an NPC or an in-game object to obtain
a quest and its subsequent objectives. In our case, our player will go and talk to the
"Blue" man (in the following screenshot) to find out what it is that they need to do. But
how do we make this blue man talk so that he can tell us what our objectives are? Glad
you asked!

184
Creating an interactive NPC that delivers quest information
Creating an interactive NPC that delivers quest
information
In many instances within a game, as you've probably experienced yourself, players obtain
quest objectives by interacting with NPCs or various in-game objectives. From this initial
interaction, the player is then presented with a series of objectives to complete in order to
fulfill the quest. In our game, we'll create something like this by adding an NPC within
our game that the player must go and talk to in order to initiate their quest. You can see
an example of them in the following screenshot:

We cannot interact with our NPC because we will handle all the interactions with the
Quest Manager, which we will come to later. Instead, we can create our NPC, which is
just a third-person character that has been placed into the word. To be sure that is not
controlled by any player, we can just remove the option for that. Just select it, and in the
Detail panel, we need to set Auto Possess Player to Disabled, as shown in the following
screenshot:

185
Creating an interactive NPC that delivers quest information

Optionally, we can change its color. You just need to find where the material of the
Mannequin is located in the Content Browser (Mannequin | Character | Materials) and
duplicate it. If you double-click on it to open it, you can find which node you need to
interact with highlighted so that you can change its color:

186
Creating an interactive NPC that delivers quest information

Once the color has been changed, save and close the file. Now, just apply the material to
our newly created NPC.

187
Creating the Quest UI &#x2013; the design
Creating the Quest UI – the design
For the Quest UI, we're going to keep it relatively simple with just text. This will be the
same for each instance of the UI from the UI that will indicate to the player where to
begin (like in the following screenshot):

Like we did in the previous chapter, we will need to create a UI that will let the player
know about the following:
When they get to the door, to open it. Since we already covered this in the previous chapters, we won't
be covering it here.
That they need to talk to the Blue Man to trigger the quest (as we saw in the preceding screenshot).
We'll discuss this in the Quest Manager section, along with letting the player know that they need to
return to the Blue Man to signify the end of the quest.
We will also create a UI that will tell the player to use the platform Use Me. We'll discuss this when we
talk about placing the final Blueprints toward the end of this chapter.
The actual Quest UI that tells the player what they need to do, what they have already done, and what is
left to complete, for example, their progress with setting the blue signs on fire. We'll discuss this now
so that you can implement your own Quest UI into your game:

188
Creating the Quest UI &#x2013; the design

To begin, if you haven't already, create a separate folder within the Content folder. Call it
Quest System. Now, we can begin to create our Quest UI just as we would create any
other UI within our game:
1. Create a UI Widget Blueprint.
2. Create a heading by adding some Text (Block); we'll call the window Current Objectives. Scale and
color it as you please.
3. Now, create some text for each objective. Make sure that each objective is a separate text (block). One
thing to know at this point is that the text that you will have inserted for collecting the Blue Signs will
not matter at this stage, so in theory, you could also leave it blank because we will be handling the text
via Blueprints later. However, so that we can get an idea about the scale, position, and overall look of
the quest UI, enter the text that you want to appear. Scale but do not color, because the color for this text
will be handled by Blueprints.
4. Remember that while you're doing this to position the anchors properly so that when the screen size is
changed the quest UI doesn't get distorted.

5. Lastly, position and decorate (for example, add a background) as you please. Once you have done all
this, you will have something that looks like the following:

189
Creating the Quest UI &#x2013; the design

190
Creating the Quest UI &#x2013; the technical side
Creating the Quest UI – the technical side
Now, it's time to bind the text of our interface to certain functions.
Before we do that, we need to create four variables:
BlueSignsFound: An integer variable that keeps track of how many Blue Signs the player has found.
TotalNumberOfBlueSigns: Keeps track of how many Blue Signs there are in total in the map.
DoorOpened: A Boolean type. If true, it means that the objective of opening a door has been fulfilled.
RoofReached A Boolean type. If true, it means that the objective of reaching the roof has been
achieved.

Please notice that we don't want to define any logic inside our Quest Widget. As a result,
we will assume that these variables will contain the correct values, but they will be
updated by an external entity (the Quest Manager, as we will see). As a result, we just
need to make those public (open the yellow eye next to the variable) so that the Quest
Manager will be able to update those accordingly. As for the Quest Widget, we can be
sure (hopefully) that they will contain the correct values. The following screenshot shows
the four variables:

Let's start with the objective setting the blue signs on fire. In the designer tab, next to
where you type in text, there is a button that allows you to bind the text to a function.
Let's do it—Unreal will create a new function for us. The logic behind it is very simple:
we just need to check how many objects we have found:

191
Creating the Quest UI &#x2013; the technical side

Then, we need to create a similar binding for the different colors of the objectives. In
fact, we want the text color of an objective to turn green when it is complete. So, next to
the color, there is again a button to bind that color to a function. We need to do it for
each of the objectives. As for the code, let's see these functions one by one.
The function that turns the blue sign objectives green, needs to check if the number of
BlueSignFound is actually the same as the total number. If so, it sets the text to be green;
otherwise, it sets the text to be white:

192
Creating the Quest UI &#x2013; the technical side

For the Door objective, the process is easier. If the Boolean that checks if the door has
been open is true, we select a green color; otherwise, we go for the white one:

193
Creating the Quest UI &#x2013; the technical side

In a very similar fashion, we will have it so that if the Roof Reached Objective has been
completed, then we will bind the color to be green with a select node; otherwise, we just
go for a white color:

194
Creating the Quest UI &#x2013; the technical side

Once you have done all this, check that it all compiles correctly. We can now close the
Quest Widget.

195
The Quest Status
The Quest Status
We need to find a way to keep track of the status of our quest. There are many ways to
achieve this, but the cleaner way is to use an Enum. So, let's create a Blueprint Enum
called EQuestState in our Quest folder, as shown in the following screenshot:

Now, double-click to open it.


An enum is basically a list of names that are associated internally with an integer. They
are really easy to set up and use, especially in Blueprint. Now, let's think about the
possible states a quest can be, and then add them to the enum. It is better at this stage to
add them in order so that it keeps the scripting easy to read. For example, we can use Not
Enable, InProgress, ObjectivesCompleted, Success, and Failed, as shown in the following
screenshot:

196
The Quest Status

Save the enum and close the window. Now, it's time to face the Quest Manager, the core
of our simple Quest system.

197
The Quest Manager
The Quest Manager
Now, we're going to create a Blueprint that will handle all the progress of the quest,
including starting it and closing it. So, let's create a new Blueprint actor inside the Quest
System folder and name it BP_Quest Manager.
Before we open the Quest Manager, we need to create another Blueprint because, in the
code of the Quest Manager, we need to reference it. So, in the same folder, create
another Blueprint and name it ObjectToFind, which will be the Blueprint handling the
interactions between the player and the Blue Signs.
Next, let's open the Quest Manager. We need to add a couple of components:
The first component is a Box Collision so that the player will be able to interact with the Quest
Manager (as we did for all the other kind of interactions in the previous chapters). We can scale it up,
maybe around 6 times.
The second component is going to be a text render. In this way, we can notify the player when a quest is
available, ready to be completed, or completed. Scale the text up and give a good offset along the z-
axis. Also, as the initial text, we can have Start Quest Here. This is what the Quest Manager should look
like in the viewport:

The hardest part is the code. First of all, we want our Quest Manager to be interactive.
As a result, we need to add our Interactable Interface. In this way, the player will be able
to interact with the Quest Manager. Create a custom event—we can name it Start
Interaction. Then, from the interface function, we just call this event, as follows:

198
The Quest Manager

Now, we want to add a new variable to our Quest Manager, which is the quest state.
The type is the enum we created earlier. Therefore, the Quest Manager is able to track
the status of the quest. Moreover, we keep this variable public so that other Blueprints
can have access to it.
This is a small system and we are the only one working on it. In larger projects, we
usually want to guarantee that the Quest Manager is the only one updating the quest
status variable. As such, the Quest Manager needs a custom function that returns the
value of the quest state variable, without giving the public access to it.
At this point, we will need another four variables. They are going to be the same ones
that we added to the Quest Widget. Thus, we need the following variables:
ObjectCollected: An integer variable that keeps track of how many blue signs the player has found.
TotalObjectsFound: Keeps track of how many blue signs there are in total in the map.
OpenDoorOjective : A Boolean type. If true, it means that the objective of opening a door has been
fulfilled.
RoofObjective : A Boolean type. If true, it means that the objective of reaching the roof has been
achieved.

Now, we are ready to build our code. To begin, follow these steps:
1. Drag the enum variable into the graph, and from there, add a switch. This is a control flow node that
changes the flow according to the value of the quest State variable.
2. Connect the Start Interaction Event to the switch. As a result, every time the player interacts with the
Quest Manager, based on the quest status, we do different things. We will use only the Not Enable and
the Objectives Completed states (since we want the player to interact in these two moments with the
Quest Manager):

199
The Quest Manager

Now, on the Not Enable branch, we need to continue our graph. I'm going to place a
sequence node to keep things easier to read, but it is not necessary. If the flow continues
in the Not Enable branch, then this is the first time the player has interacted with the
Quest Manager, and we need to do some initialization:
1. We need to change the quest state to In Progress.
2. We need to create the Quest Widget, promote it to a variable (so we can keep track of it), and add it to
the viewport so that it is visible.
3. We need to get all the Actors of a Class ObjectToFind (the Blueprint we created at the beginning of this
section) and save the length of the resulting array into the Total Objects Found variable. As a result, it
doesn't matter how many blue signs you place in the map—the Quest Manager will know how many
there are to be found.
4. We update the Quest Widget (we will implement this custom event in just a second) and update the text
of the Text Render component to an empty string.

This is how we can do all of this:

200
The Quest Manager

Going back to our Switch node, let's implement the Objective Completed branch. In this
case, we want to do the following:
1. Update the quest state to finishes.
2. Remove the widget from the Viewport (if you want, you can destroy it as well).
3. Change the text of the Text Render component to Quest Completed.
4. (Optionally) Reward the player. In this mini-game, we don't have anything to reward the player. But as
an exercise, you can spawn a gold item for the player to pick up.

These steps can be done in the following way:

201
The Quest Manager

The next function that we need to implement is the Update Quest Text custom event.
Here, we basically need to use the Quest Widget reference to set its variables to the same
values of the Quest Manager. So, the Quest Manager will take care of updating its
variables, and every time they are updated (as we will see in a second), the Quest
Manager will reflect those in the Quest Widget. As we programmed the Quest Widget,
once the values of its variables are updated, it will take care of updating the text and the
color of the different objectives. The code for this part is pretty straightforward, since we
just need to assign the four variables in a row:

Now that the Quest Update function is done, let's think about how the other Blueprints
can update the progress of the quest. In particular, we want to create three custom
events: Add Object Found, Roof Reached, and Door Opened—one for each of the
objectives that the player can do. In Add Object Found, we just increment the variable
Objects Found; in Roof Reached, we set its respective Boolean to true. The same goes
for Door Opened.

202
The Quest Manager
Now, we need to make all of these three custom events converge, since the following
steps apply every time one of these three events have fired and in particular. We need to
do the following:
1. Call the Update Quest Text event so that our Quest Widget is up to date.
2. Check whether the number of objects found is equal to the total AND the door is opened AND that the
roof has been reached. If all of these conditions are true, with a branch node, we set the quest state to be
Objectives completed.

This is the final graph we should have:

This completes the Quest Manager, but we still have some more Blueprints to set up.
203
Blue Sign to Set on Fire
Blue Sign to Set on Fire
If you haven't created this Blueprint (ObjectToFind), do it, and then add to the Find All
Actor of class node of the Quest Manager to reference to this Blueprint. Otherwise, if
you already have it, double-click to open it.
This Blueprint will be simple. We need a Box Collision component (and scale it up to a
reasonable size) so that the player is able to interact with it and that's it. Optionally, you
can add the mesh of the blue sign, but since we have already placed them in the map, I'm
just going to put them in the same location in this Blueprint.
Whether you need to add the mesh depends on what you are going to do with the blue
signs. If they are only necessary for one mission and then the rest of the blue signs are
just decorations for the game, then this approach might just be right, but if this is a
repetitive thing (such as picking up an object), then the mesh should be included in the
Blueprint (as we did for our pickup system in the previous chapter).
Then, we need to add a public variable for the type of Quest Manager. In fact, we want
to be able to access its function and quest state. Since this is a simple quest system, we
set the value of this variable in the Details panel once this Blueprint has been placed, so
don't forget to do it later!
Next, we need to add the Interactable interface and implement its function. In the
Interact function, we switch on the quest state retrieved from the Quest Manager since
we want to interact with this Blueprint only when the Quest is InProgress. From here, we
need to perform the following steps:
1. Call the Object Found function on the Quest Manager so that we can notice that the player has
progressed through the quest.
2. Destroy this actor, since the player has interacted with it. We don't want any more interaction, so we
can remove this Blueprint from the world.
3. Spawn a fire particle system with the Spawn Emitter At Location node. If you don't have a particle
effect in your project files, don't worry, because the engine has one. When you start selecting the emitter
from the node, you will see a button called View Options on the bottom right. From there, you will be
able to check the Show Engine Content checkbox. Now, you can select a fire emitter named
TutorialParticleSystem, which is a fire. To enable this option, take a look at the following screenshot:

204
Blue Sign to Set on Fire

The final graph will look something like the following:

205
Blue Sign to Set on Fire

206
Reaching the roof
Reaching the roof
In a very similar way to how we created the Blueprint for when we found the Blue Sign,
we can create another Blueprint actor for when the player reaches the roof. For instance,
we can name it BP_PlaceToGo. Once again, we add a Box Collision component and
scale it up. Then, we add the Quest Manager variable that we need to assign from the
Detail panel once this Blueprint has been placed in the world.
This time, instead of making this object interactable, we just add a Begin Overlap Event
with the Box Collision (like we did back in Chapter 1, Getting Unreal, and Chapter 2,
Understanding the Basics of Blueprints) and as we did there, we check that it is actually
our Third Person Character with a Cast. If so, we do the same as we did for the Blue
Signs Blueprint. We call the Roof Reached event from the Quest Manager, we destroy
this Blueprint, and optionally we can spawn a fire emitter. This is the final code:

207
Door that opens
Door that opens
We already have a door that opens—we did this in the last chapter. Therefore, to begin,
follow these steps:
1. Duplicate the door we made in the previous chapter and modify to make it suitable for our quest.
2. You can rename the copy BP_QuestDoor and move it inside the Quest System Folder.
3. Since we are going to place this door in a very narrow passage, you can scale the size of the Text
Render down.
4. Then, we want to add the Quest Manager variable. Once again, you can set this in the Details panel.

Now, we need to modify two little things to make it work as it should:


1. After the Begin Overlap and the End Overlap events in which we set the visibility, we need to switch
based on the quest state (from the Quest Manager) and change the text depending on whether the quest is
Not Enable (into something like You need to start a quest first or the state is In Progress into press E to
Interact). This is what the graph should look like:

208
Door that opens

2. Once the player starts the interaction, we want to execute the timeline, but only if the quest state is on In
Progress. Also, we need to notify the Quest Manager that the door has been opened. This is what the
graph should look like:

209
Door that opens

Once the notification of the Door Objective has been completed, connect to the Finished
pin of the Timeline, that is, if you want to grant the objective as being done when the
player starts to open the door, or when they have completed the level.
This concludes the coding part. Now, we need to place these Blueprints in the
environment.

210
Placing the blueprints in the environment
Placing the blueprints in the environment
Now that we have all of these Blueprints, it's time to place them in the environment.
We'll cover each of the different Blueprints that we have created and how and where to
place them within our game environment. Of course, this may vary depending on how
you created your map or which map you are using (if you're using a preexisting one, for
example).

211
Quest Manager
Quest Manager
Now it it is time to place the Quest within our level. To do this, simply place the Quest
Manager next/on to the blue guy, like we have done in the image below:

212
Platform
Platform
Since we would like to use the interactable platform we created in past chapters, we can
add a generic spatial UI to let the player know that they need to use the platform. We can
do this by placing a simple Use Me UI element within the environment, like in the
following screenshot. Since this part doesn't really involve any interaction, you can just
place it within the environment once you have created it. You can place the platform
underneath, and if you want you can change its material as well:

Now, where could the platform could go? We need to spot a place. For instance, the spot
that's shown in the following screenshot is perfect. Make the end part of the platform
move there (if the player falls through that platform, you can add a Collision Volume).
Then, on top of it, we can add our Roof Objective Blueprint (BP_PlaceToGo), as in the
following screenshot:

Let's say you want the platform to come back; for example, when the player falls off the
platform, you don't want to prevent the player from reaching the roof anymore because
213
Platform
the platform won't come back. Therefore, to make it come back when the player is no
longer on it, we need to change the platform Blueprint in the following way: drag the
Finished pin of the Timeline into a Delay node.
Then, connect the Delay node into the Reverse pin of the Timeline, kind of creating a
twist. As a result, after the player uses the platform, after 5 seconds, the platform will
come back. This is what the twist (the code) looks like:

214
Blue Signs
Blue Signs
Now, we need to place the Blue Signs Blueprint (BP_ObjectToFind) on top of the Blue
Signs you have placed in the map (you can place the blue signs where you want them
within the environment, depending on how you want to set up your objectives;
furthermore, you can place as many as you like as the Quest Manager will take care of
the rest).
The following screenshot shows you where I placed the first Blue Sign with the Blueprint
on top:

Do the same for the remaining Blue Signs (three, in my case) within the level. They will
look as follows:

215
The door
The door
Place the quest door at the entrance, but be careful that the text render is facing the
correct way (outside) and make sure that the collider is big enough to trigger the text, like
in the following screenshot:

216
&#xA0;Quest Manager References
Quest Manager References
If you haven't yet already, check that all of these Blueprints (that we have placed) have
the Quest Manager reference set. This is very important, since otherwise, our quest
system will not work. So, select every Blueprint you have placed and in the Details Panel,
make sure to select the Quest Manager from the drop-down menu:

217
Testing our level
Testing our level
Finally, save everything so that we can test it in-game. When you test it, it should look
something like what's shown in the following screenshots.
When you hit play, this is what you should see near the Blue Man, where the Game
Manager is:

When you reach the door, but you still haven't started the quest, you should see the
following:

When you set a blue sign on fire, you should see the following:

218
Testing our level

Once a player has completed a quest objective, it will turn green:

When a quest has been completed, all of the objectives should be green, and the Quest
Manager should notify the player to go back to the Blue character:

219
Testing our level

Once the Quest has been completed, this is how it should appear:

220
Extending upon what you have learned here
Extending upon what you have learned here
You may think that after tackling a chapter like this, could it be the end? Think again.
Even if we've covered the basics, like all of the chapters so far, there is plenty of room to
improve, push, and challenge yourself. Here are a few ideas to get you motivated:
Try adding different objects or even using different projects to create different types of games such as a
horror/survival, adventure, or narrative driven adventure game.
Using everything that you have learned so far in this book, do you think that you could create a more
challenging environment that tests the player?
Are there any other things that you could get the player to do as part of their quests? Think about some
other things that you can get the player to do and add them to their quest.
Try making the UI a little bit nicer. Perhaps think about creating an opaque background or changing the
font, color, size, and so on.

221
Summary
Summary
This time around, we have not only reached the end of this chapter but also completed
our first project. Well done! Thanks for sticking through it all so far. But, alas, it's not the
end. Chapter 7, Reducing Loneliness with AI, brings with it a new adventure for us to
begin. For now, let's focus on what we have achieved so far. In a broader sense, this
project has allowed us to learn and create most of the basic features that you will
experience within a platforming game. We've learned about materials, UI, interaction,
triggers, and colliders, to name a few. We've added an inventory and quest system to
make use of the game's objects and to give us goals to achieve. Lastly, here, in Chapter
6, Creating an Adventure, we've learned about level design and have created a game
level that has brought together all the things that we have learned about within this
project and implemented them into a fully functional level. So, effectively, this chapter
has given this first project a sense of closure in that we've been able to create an entire
level from start to finish that has some basic yet essential gameplay features.
Next, in Chapter 7, Reducing Loneliness with AI, we'll be learning about a whole range of
new things, not to mention extending upon what we have already developed both here
and in the earlier chapters of this book. We'll look at how to create AI using Blueprints,
as well as how to create a navigation (wandering) behavior so that our AI can move
autonomously. Lastly, we'll look at how to create a navigation (following) path behavior
so that our AI follows an explicit path. So, let's move on and create some AI!

222
Section 2: Making It Feel Like a Game
Section 2: Making It Feel Like a Game
In this section, you will learn about adding features to the game using Blueprints. This
includes additional features such as audio, special effects, and AI. In this section, we will
also create our second game, which will be a survival maze, the creation of which will
allow us to build upon what we learned in the previous chapters.
We will be covering the following chapters in this section:
Chapter 7, Reducing Loneliness with AI
Chapter 8, Upgrading the Gameplay
Chapter 9, Upgrading the AI
Chapter 10, Adding Audio
Chapter 11, Making It Pretty
Chapter 12, Game Analytics, Debugging, and Functional Testing
Chapter 13, Level Streaming and World Composition

223
Reducing Loneliness with AI
Reducing Loneliness with AI
Welcome to Chapter 7, Reducing Loneliness with AI. Think of this chapter as a fresh
start, a new year, a new beginning where we will begin the second part of our journey.
Before we get stuck into this chapter, let's cover what this second project will be about.
We will be creating a survival maze shooter, where we will be adding artificial
intelligence (AI) and more immersion to our game experience through the use of audio
and level streaming. However, for this chapter, you will need to start thinking about
whether you ever feel lonely. Who needs friends when you can create them? Or enemies,
for that matter. Whether friend or foe, creating AI is nothing we can't handle in
Blueprint! We'll be covering the following in this chapter:
Introduction to Behavior Trees and Blackboards, and how to use them when creating AI
How to create AI using Blueprints
Creating navigation (wandering) behavior so that our AI can move autonomously—it will wander
Create navigational (following) path behavior so that our AI follows an explicit path

So, let's get to it and create some friends!

224
Introduction to Behavior Trees and Blackboards
Introduction to Behavior Trees and Blackboards
Things are about to get a bit more technical from here on out. We will now learn how to
use the two main Unreal AI Framework structures—Behavior Trees and Blackboards. To
begin, we will look at what Behavior Trees are and focus on understanding their principal
components. The theory behind this is important because it will make the process a lot
easier later on when it comes to creating AI behavior. Next, we will extend upon our
knowledge by learning about Blackboards, what their importance is in creating AI, and
how we can integrate them with Behavior Trees. Then, we will cover AI controllers that
use Behavior Trees. This is very important when it comes to implementing the rest of the
techniques within the remaining projects in this book, which is why we are covering it in
a lot of detail here so that you can establish a strong foundation to build upon.

225
What is a Behavior Tree?
What is a Behavior Tree?
The easiest way to think about a Behavior Tree is to imagine it like a brain—more
specifically, the brain of our AI. The structure of a Behavior Tree makes it easier to
encapsulate the behaviors that we create, with the flexibility to make the AI behave the
way that we want it to. For example, how behavior is executed, and in what order
depending on certain conditions will determine its response to the player and its influence
in the overall game experience. I am sure that you can think of a time when the AI has
been so terrible that it affects gameplay. Before we continue, if you have any experience
with Behavior Trees in other technical/programming contexts, it is important to
understand that they are a bit different within the context of Unreal. Moreover, it is
important to highlight another difference, in that Unreal Behavior Trees are read from the
top to bottom, and the nodes will be executed from left to right.
To understand how Behavior Trees are different in Unreal, visit the following
link: https://docs.unrealengine.com/en-
US/Engine/AI/BehaviorTrees/HowUE4BehaviorTreesDiffer.

226
Components of a Behavior Tree
Components of a Behavior Tree
To begin our journey to understanding all of this, let's start with Behavioral Trees, which
consist of five nodes types:
Root
Task
Composite
Decorators
Service

To understand how they are all linked together within the schema of a Behavioral Tree,
we can think of it as a top-down execution process. Basically, when you execute a
Behavioral Tree, it will run from the Root to the next Composite node and its children
(left to right) until one of the conditions has succeeded. During this entire process, the
procedure will traverse all the different branches (Composite nodes) until we reach
the leaves (Task nodes). In this case, the final AI behavior is based on those leaves—
or Tasks. It is quite important to note that a Task can fail, though. For example, if the AI
is not able to complete its Task due to environmental factors where they are prevented
from doing so. The fact that a Task can fail will be useful to understand when it comes to
understanding how Composite nodes work. After all, a decision-making process is just
choosing the right Task to perform to achieve a goal (for example, chasing the player).
Briefly speaking, this is because when a Sequence node is initiated (within Composite
nodes), they will play the children in sequence and only stop when one of the
children fails. Don't worry too much for now if this is a bit overwhelming since we're
going to cover everything in more detail later in this chapter.

227
Root
Root
The root node is the beginning of a Behavior Tree. The tree needs to begin somewhere,
so the Root node is just where the tree starts its execution. It is important to note that the
Root node can have only one child and it must be a Composite node. You cannot attach
any decorator or service to the root. If you select the root node, it doesn't have any
property, but you will be able to assign a Blackboard (which we will talk about later in
this chapter).

228
Tasks
Tasks
Now, when we think of a tree, we often picture a large trunk with branches, and on those
branches are leaves. In the context of UE4, those leaves are what we call Tasks. These
are nodes that perform various actions such as move an AI and can have Decorator or
Service nodes attached to them. However, they do not have an output connector. What
this means is that they do not play a role in the decision-making process, which is left
entirely to Composite nodes, but rather they define what an AI should do if that Task
needs to be executed. Please note here that Tasks can be as complex as you like. For
example, they can be as simple as waiting for a certain amount of time, to as complex as
solving a puzzle while shooting at the player. Huge Tasks are hard to debug and to
maintain, while small Tasks can make the Behavior Tree easily overcrowded and huge.
As a good AI designer, you should try to find a balance for the size of the Task and write
them in such a way that can be reused in different parts of the tree (or even in other
trees).

229
Composite
Composite
Composite nodes are at the core of the decision-making capabilities of Behavior Trees in
Unreal, and understanding how they work is key. As per version 4.20 of Unreal, there are
three kinds of Composite nodes: Selector, Sequence, and Simple Parallel. The last one
has been added recently, and you will find that using a combination of Selectors and
Sequences will be able to cover most of your cases. Here is how they work:
Selector: This kind of node will try to find one of its children to execute, which means it tries to find
either a branch (so, another composite node attached as a child) or a Task (another child, but it is a leaf)
to execute. So, the Selector starts from the left-most child node and tries to execute it. If it fails (either
the Task failed to be executed, or the whole branch failed), then it tries the second left-most, and so on.
If one of the children is a successful one, which means that either the Task has been completed or a
whole branch, then the Selector reports Success to its parent and stops executing other children. On the
other hand, if all the children in the Selector report a fail, then the Selector reports a fail to its parent as
well.
Sequence : This kind of node works a bit like the opposite of the Selector. For a Sequence to report a
success to its parent, all of its children must report a success. This means that the Sequence will start
executing the left-most child node. If it is a success, it carries on with the second left-most, and so on if
it is successful as well. If all the children until the right-most are a success, then the Sequence reports a
Success to its parent. Otherwise, if just one of the children fails, then the Sequence stops executing its
children and reports a fail to the parent.

Simple Parallel: This is a particular kind of Composite node, which is used in specific cases. In fact, it
can only have two children. The left-most must be a Task, where the other one can be either a Task or a
Composite (giving birth to a sub-tree). The Simple Parallel starts to execute both its children in
parallel, although the left-most is considered the main one. If the main one fails, it reports a fail, but if
the main succeeds, then it reports a success. Based on these settings, once it has finished to execute the
main Task, it can do either of the following:
Wait for the end of execution of the sub-tree or directly report success.
Fail if the main one to its parent and stop executing the sub-tree.

In this way, Composite nodes can decide which Tasks to execute, and based on what
their children report (fail or success), the Composite node reports back (either fail or
success) to their parent. If the only-child of the root (which is necessarily a Composite
node) reports back a success to the Root, then the tree has been executed with success. A
good Behavior Tree design should always allow for a success back to the root.

230
Decorators
Decorators
Decorator nodes (also known as conditionals) are attached to either a Composite or Task
node. Decorator nodes make decisions on whether a branch in the Behavior Tree or even
a single node can be executed. In their essence, they check to see if something should be
occurring; if so, it is a condition. In other words, a Decorator can check whether it is
worthwhile continuing on that branch and can report a preventive fail. If it's based on the
condition, we will know for sure that the Task (or sub-tree) will fail. This will let us avoid
trying to perform a Task (or sub-tree) that is impossible (for any reason: lack of
information, the goal is no longer relevant, and so on).
For a (simple) example, imagine that there is a sub-tree dedicated to killing the player (it
will make a decision on trying to kill the player). Checking if the player is in range (and
not from the other side of the map), or even if the player is still alive, might give us a
preventive fail without executing that sub-tree. Consequently, the tree can continue to
other events or parts of the tree, for example, in another sub-tree that will be responsible
for the wandering behavior.
For those who are familiar with conditional nodes (for example, in blueprint), it is
important not to confuse them as Task leaf nodes in UE4.

231
Service
Service
Service nodes attach to Composite or Task nodes and will execute if their branch is being
executed. This means that as long as a node is below the node where the service is
attached, it doesn't matter how many levels of parent-children are being executed, since
the Service will run as well. This means that Service nodes are the eyes on the tree
execution, meaning that they observe and regulate the behavior of the tree beneath by
providing a specific service. In fact, they run continuously (if the sub-tree is active) and
can perform checks and/or update Blackboard (see later) values in real-time. Service
nodes are really specific for your Behavior Tree application, so there are only two default
ones. An example of their usage might be providing/updating information to the sub-tree.
Imagine that the sub-tree tries to kill the player, but at the same time, the enemy needs to
take cover to reduce the damage it takes. However, the enemy might be moving in the
map, or the player might destroy the current cover where our AI is hiding. Thus, the sub-
tree needs information regarding which is the closest cover, the safest, and still in range
of the player. A service can update this information in real-time so that when the sub-tree
needs to use the data regarding the cover, they are ready. In this particular example of
finding cover, running an Environment Query on the Service is a dynamic way of doing
so (we will face this topic later in this book). Otherwise, the Service might check certain
specified points in the map that have been placed by a designer and evaluate them to find
out which one is the best. As you can see, Service nodes can be really powerful, but they
are also specific for the application you are using them for so that they are specific for
the AIs of your game.
Service nodes replace traditional Parallel nodes in other Behavior Tree systems.

232
What is a Blackboard?
What is a Blackboard?
Now that we have a better understanding of what a Behavioral Tree is and what its
components are, it's time to understand the next key component—the Blackboard. A
human's behavior is as complex and interesting as the next. If we consider that a
Behavior Tree is a brain, we can think of a Blackboard as the memory—that is, the
memory of the AI. The Blackboard stores (and sets) key values for the Behavior Tree to
use. They are fairly simple, just a bit more advanced than a data structure. The only
difference lies in the possibility to assign a particular Blackboard to a Behavior Tree,
which is shared by every node of the tree. As a result, each node can read and/or write
back into the Blackboard.
For those of you who are familiar with the Design pattern of Blackboards (in the context
of Software Engineering), here, within the context of Unreal, they just cover the role of
holding the memory (basically providing data storage) for a Behavior Tree.
It works like a dictionary, in which a key corresponds to a specific value type (for
example, a vector, a float, an actor, and so on… even another Blackboard key). So, by
using or recalling the key, it is possible to write or read the associated value. Another cool
feature of Blackboards is that they can be extended through inheritance. This means that
another Blackboard can be a parent, and the child will inherit all the parent's pair key-
values, plus some specific ones contained in the child itself.

233
Creating our AI project
Creating our AI project
From now on, we will start to get out feet wet and get a gist of what we have learned
about so far. Let's begin by creating our second project. To start, let's create a New
Project, but this time, select the First Person shooter Blueprint, as shown in the following
screenshot:

234
Creating our AI project
Next, to begin setting up our files, we need to do the following:
1. Create a new folder in the Content Browser for the AI. We will call it AI.
2. Then, create an AI controller and call it BP_AIController (Add New | Blueprint Class | All Classes |
Object | Actor | Controller | AIController). You can see an example of this in the following screenshot:

The goal of the remaining part of this chapter is to create an enemy that will randomly
wander throughout the map. But don't worry—we'll give our AI more abilities in the
following chapters, such as the ability to chase the player.

235
Creating the Blackboard
Creating the Blackboard
Now, we need to add a Blackboard (within the AI folder). To do this, go to the Content
Browser and select Add New | Artificial Intelligence | Blackboard. For now, we will call
our Blackboard BB_Blackboard.
Now, open up the BB_Blackboard and add a new key of type Vector, like in the
following screenshot:

Then, call this key Destination. You can see an example of this in the following
screenshot. This Blackboard key will hold a random position that will tell the AI which
direction to head toward:

236
Creating the Blackboard

That is all we need to do for the Blackboard. Save it, and now, let's start creating our
Behavior Tree. Call it BT_WanderBehaviorTree.
Since it is not possible to have multiple Blackboards on the same Behavior Tree, you can
use inheritance with the Parent and Child within the Blackboard Details panel, like in the
preceding screenshot (on the right).

237
Setting up a Behavior Tree
Setting up a Behavior Tree
Now, we need to deconstruct the behavior of our AI character so that we can build our
Behavior Tree. In particular, we will perform a sequence of three actions (Tasks):
1. Select a random location (we need to create this from scratch since it is not a default action within a
Behavior Tree).
2. Move the character to a random location.
3. Make the AI character wait for a certain amount of time before repeating the loop (for example, moving
to a new location).

Let's begin by opening up our Behavior Tree. Make sure that, in the Details Panel, we
have our Blackboard assigned, like in the following screenshot:

T start building our BehaviorTree, we need to follow these steps:


1. Create a Sequence node from the Root (node).
2. From the sequence node, drag out two tasks (like in the following screenshot):
The first will be Move to (Tasks | Move To)
The second will be Wait (Tasks | Wait):

Make sure that the Move to Blackboard Key is set to Destination (the vector that we
created in the Blackboard) in the Details Panel. Similar for the Wait node, make sure that
238
Setting up a Behavior Tree
you have a timer set that suits your needs (for example, 5 seconds, 1 minute, and so on).

If you want to have a random waiting time, you can tweak the random deviation
parameter, as shown in the following screenshot:

Now, it's time to create a custom Task so that we can set our random location for the AI.
In particular, this Task will take a radius as input, where the random location will be
selected and write this location inside the destination vector. To create a new Task, press
239
Setting up a Behavior Tree
the New Task button in the top bar. As a result, a new Blueprint will be created inside the
Content Browser.
If you already have tasks within your project, then you will need to select
BTTask_BlueprintBase.
Before we continue working, close the Blueprint Editor and in the Content
Browser (currently opened folder), you will see the newly created Task with the
following name: BTTask_BlueprintBase_New. Rename it
to BTTask_RandomLocation and place it within our AI folder (if it isn't there already).
Now, double-click on BTTask_RandomLocation to open the Blueprint Editor again (you
might need to click on Open Full Blueprint Editor like in the following screenshot):

Once the editor is open, we want to execute some code when the Task has been
initialized (some Tasks may require more than just the initialization to complete).
However, since in this case we just need to assign a variable, we can place all of our logic
inside the initialization. Now, in the My Blueprint Panel, hover your mouse
over Functions. Here, you will see a menu item titled Override. Click it and
select Receive Execute AI. You can see an example of this in the following screenshot:

240
Setting up a Behavior Tree

By doing this, it will place an event node that will fire when the Task needs to be
executed (initialized). Before we can start adding our logic, we need to have two
variables within the Task:
1. LocationTo with the variable type Blackboard Key Selector (Structure | Blackboard Key Selector),
like in the following screenshot. The Blackboard Key Selector allows us to dynamically refer to a
variable within the Blackboard of the Behavior Tree where this Task is running.
2. Radius with the variable type Float, which is the maximum radius from the AI character's position from
which we will select a random point:

Now, the final step here is to make both of these variables public. We can do this by
241
Setting up a Behavior Tree
simply opening the eye next to the variable name, like in the following screenshot:

Now, let's begin by creating our logic within the BTTask_RandomLocation Blueprint
Event Graph.
First of all, we need to follow these steps:
1. We need to retrieve the AI character's location, which we can do by dragging out the Controlled
Pawn () pin and connecting it to the GetActorLocation (Utilities | Transformation | GetActorLocation)
node.
2. Now, we can connect the ReturnValue pin
in GetActorLocation into GetRandomReachablePointInRadius (AI | Navigation |
GetRandomReachablePointInRadius).
3. Lastly, drag the Radius variable and connect it with
the Radius pin within GetRandomReachablePointInRadius.

You can see an example of this in the following screenshot:

242
Setting up a Behavior Tree

The GetRandomReachablePointInRadius node is where all the magic happens. In fact,


it will select a random point within the radius that we have specified, starting from the
position of our AI character. In addition, the node will guarantee that this random point
will be reachable in terms of the built-in navigation system of Unreal. In terms of the
navigation system, we will build this later on in this chapter. In any case, we want to
verify whether the node has succeeded in retrieving the point by either returning fail or
succeed for our AI task. We can do this in the following way:
Drag the Return Value pin in GetRandomReachablePointInRadius and select Branch (Utilities | Flow
Control | Branch).
Now, connect the output pin from Event Receive Execute AI and connect it to the input pin of
the Branch node.
Then, drag the False pin from the Branch node and connect it to Finish Execute (AI | Behavior Tree |
Finish Execute). Make sure here that the Success pin in the Finish Execute node is not enabled. In this
way, we can be sure that the Task will report a fail.
Next, drag the True pin within the Branch node and connect it to Set Blackboard Value as Vector (AI
| Behavior Tree | Set Blackboard Value as Vector).
Now, drag our LocationTo variable and connect it to the Key pin within Set Blackboard Value as
Vector.
Then, from the GetRandomReachablePointInRadius, connect the RandomLocation pin to
the Value pin in Set Blackboard Value as Vector.
Finally, drag the Set Blackboard Value as Vector and connect it to Finish Execute . However, this
time, make sure that the Success pin is enabled.
Compile and save the task to make sure that everything is connected as it should be. You can see an
example of the final Blueprint in the following screenshot:

243
Setting up a Behavior Tree

To summarize what we have just completed, if the AI task can find a random point, we
assign this point to our Blackboard and terminate the Task with a success. Otherwise, the
Task will fail.
Now, let's go back to our Behavior Tree and add the task that we have just created. From
the Sequence node, drag a New Task and select BTTask_Random_Location. Once you
have done this, you will have a finished Behavior Tree, like the following one:

244
Setting up a Behavior Tree

Now, just to make sure that everything will run properly, select
the BTTask_Random_Location and in the Details Panel, make sure that under Default,
the Location To is set to Destination and that the Radius is set to a reasonable number,
such as 3000. You can see an example of this in the following screenshot:

245
Setting up a Behavior Tree

246
Adding navigation
Adding navigation
The navigation system in Unreal is very powerful and has many parameters. However, it
can be used out of the box in a very simple way. In fact, we just need to specify what
part of the map that we want our AI character to be able to walk in. This can be achieved
by going in the Modes Panel and, under Volumes, selecting Nav Mesh Bounds Volume:

Now, drag this volume into the map and scale it to enclose all of the first-person example
map (or your own map, if this is the case). If you press the P key on your keyboard, you
will be able to see where the AI character can walk (keep in mind that it might take a
second or two to load, even on a relatively powerful computer). Therefore, by doing this,
you can see whether the navigation data is set up correctly, which will look something
like what's shown in the following screenshot:
247
Adding navigation

As you can see, the parts that are green are areas where the AI can move to. However, it
is important to keep in mind that, at this stage, this doesn't include areas that would
require the AI to jump (for example, the green areas on top of the blocks, which for now
are not reachable by our AI). Since at this stage we don't need more complicated
navigation, we're done for now.

248
Importing AI characters
Importing AI characters
Since we are using the first-person shooter template, we do not have a
character per se (we only have the upper limbs of the player). Because of this, we will
need to import a character so that we can actually have something running around us. For
example, we can import the character from the third-person example project, which we
used in the first project of this book. If you've followed along and have created the first
project, we can import it from there. Otherwise, you can either create a new third-person
example project or import characters from the asset packages from the Unreal
Marketplace (which may require additional setup). For this purpose of this example, we'll
be adding our AI character as if we were importing it from our previous project.
To begin, follow these steps:
1. Open the project that you want to import the character from.
2. Then, in the Content Browser, navigate to ThirdPersonBP | Blueprints, right-click
on ThirdPersonCharacter, and select Asset Actions | Migrate

3. At this stage, Unreal will ask you if it is fine to migrate a long series of assets because the engine will
migrate not only the asset that you have selected but also all its dependencies (for example, textures or
animations that are associated with the character). Here, just select OK.
4. Now, you will be prompted to select the destination folder to save the character in. Make sure that you
select the Content Folder of your current project.

Once you have done this, you will see a pop-up that informs you that the assets have
successfully migrated into your new project. Once we have our character within our
project, all we need to do to set up the AI character is to make it ready to be used by the
AI. In this simple scenario, the character will already be within our map and possessed by
the AI controller (which we still need to implement).
To begin, follow these steps:
1. Drag the character into the map, preferably somewhere on the ground.
2. Select the character and then in the Pawn section of the Details Panel, we need to be sure that the
following three variables are set in the following way:
Auto Possess Player is set to Disabled (already set by default)
Auto Possess AI is set to Placed in World (already set by default)
AI Controller Class is set to BP_AIController (which is the class that we created previously)

You can see this illustrated in the following screenshot:

249
Importing AI characters

The final thing that we need to do is set the AI Controller to run the Behavior Tree.

250
Setting up the AI Controller
Setting up the AI Controller
What would AI be if it couldn't take orders? It would be autonomous and, in some cases,
we don't want it to behave like that. In these instances, we want the AI to take orders and
follow a path, doing as us game developers instruct them to do. So, let's teach AI who's
boss and tell it what path to take! The AI Controller is the entity that actually controls
(any) characters. It can do this in several ways, for example, by running a Behavioral
Tree. We will do this by following these steps:
1. Open the Event Graph of the BP_AIController.
2. From here, drag the output pin from the Event BeginPlay node and connect it to Run Behavior
Tree (AI | Run Behavior Tree).
3. Lastly, set the BTAsset to the Behavior Tree that we created earlier. In this case, it needs to be set
to BT_WanderBehaviorTree.

Once you have followed these steps, you will have something that looks like what's
shown in the following screenshot:

Now that we've done this, compile and save what you've done. It's now time to test our
AI. If everything has been done correctly, once you are playing in the Viewport, your AI
should be running around and changing its position every 5 seconds:

251
Setting up the AI Controller

252
Extending upon what you've&#xA0;learned&#xA0;here
Extending upon what you've learned here
Now that we've had a look and a play around with Behavior Trees and Blackboards, it's
time to extend our knowledge with some exercises. Here, I have suggested an activity for
you to try out that will challenge what you have learned here. Keep in mind that in some
cases, you may have to do a little bit of research on your own to complete these
challenges, but they do not require that you learn a great deal more than what we have
covered in this chapter. For now, try your hand at the following activity:
Provide yourself with different scenarios (for example, park, shopping center, sports game, and so on)
and think about how the AI would move around. Take 2 or 3 examples and try to create it and test it to
see if it feels right. This is an important step if you really want to get convincing AI. For example, if
your game contains people going about their daily business, they would be walking around naturally, not
strangely.

253
Summary
Summary
Overall, in this chapter, we have covered what we will do for our second project in this
book. Next, we covered some more technical aspects such as learning about what a
Behavior Tree is and some of the things that they consist of such as tasks, decorators, and
services. Then, we learned about what Blackboards are and how they are used with
Behavior Trees, followed by creating a Behavior Tree from AI Controllers. From here,
we have developed a solid foundation that will provide us with the key knowledge to
tackle the other parts and projects in this book. As you can guess, the use of Behavior
Trees and Blackboards will be used quite a bit, so you will have many opportunities to
master them. But before we can master them, there are certain topics we need to learn
about first. So, let's keep going and move on to Chapter 8, Upgrading the AI, where we
will cover topics such as how to create complex AI systems that make the AI more
receptive to the player and their location, as well as how to create personalized tasks,
decorators, and conditions so that the AI will respond to the player!

254
Upgrading the Gameplay
Upgrading the Gameplay
Now that we have upgraded our AI, it is time to upgrade our gameplay. By this, I mean it
is time to add a bit more flow to the actions between our player and AI, which includes
being able to destroy our AI and have it respawn at another location within our map. Not
only this, but we'll also add some game conditions. Therefore, in this chapter, we'll cover
the following topics:
Setting game conditions, such as parameters for winning or losing in-game
Game states (win/lose), which will involve providing gameplay scenarios when a player wins or loses
Making AI enemies destructible so that we can create an AI that can die
A respawn system for the player and enemy after they die
Giving the player the possibility of restarting the level

255
Setting up our project
Setting up our project
Like every part of our game so far, we will need to do a bit of setup to get going and to
make sure that all of our files are kept in an ordered way. We'll start by doing the
following:
1. Creating a new folder in the Content Browser and calling it Gameplay Elements.
2. Next, we will need to create two Actor Blueprints called BP_FinalDoor
and BP_CollectableItem.

With this part done, it's now time to move on to making it all work.

256
Final door (to somewhere)
Final door (to somewhere)
To kick off our gameplay upgrade, we'll get the player to collect some items so that it will
trigger a final door to open. This can be useful for when you want the player to find a key
so that they can progress to the next level. To make this happen, in the Final Door
Blueprint, we will count how many objects we need the player to collect around the map
when the game starts. We will provide an event for the collectible items to communicate
to this Blueprint that they have been collected. Internally, the Final Door Blueprint will
keep track of how many items are remaining and when the count reaches zero, the door
will open. To achieve this, let's go through the following steps:
1. Open up BP_FinalDoor.
2. Now, let's add a component static mesh and call it DoorStaticMesh. We can set this as a static
mesh. If you don't have a particular mesh, you will find the 1M_Cube in the template project, and then
you scale it so that it looks like a door. In particular, you could use the following values: x:1, y:0.1,
and z:2. Therefore, if 1M_Cube is a cube of 1 meter, then your door would be 2 meters tall, 1 meter
wide, and 10 cm thick. But feel free to scale it as you want. Don't forget to bring it up a meter so that the
bottom of the door is located at the center. This will help you later on when you need to position the
door. You can see an example of this in the following screenshot:

3. Otherwise, you can use a custom mesh. In the example provided, with the Infinity Blade Asset Pack, you
can use the SM_Exo_Decos_Door02 asset. This is what it looks like once placed in the static mesh
of our BP_FinalDoor:

257
Final door (to somewhere)

4. Add a custom event and call it OpenDoor. You are free to implement as you like, for example,
Explodes/Sides and so on. In this case, we're just going to destroy it. In fact, the reason why we are
creating an event is so that you can extend the functionalities (for example, SFX or VFX or whatever
suits your need) later on, and as a result we will have modular code that can be easily managed—even
if at the current stage it is as simple as destroying the door. Therefore, from the Event, drag a Destroy
Actor node from the output pin. This will ensure that when the Open Door event is fired and that the
Final Door will be destroyed, leaving an opening to reach the final point of the map. This is what the
Event Graph should look like so far:

5. Create a new variable of type integer and name it RemainingCollectableItems. As a result,


we will be able to keep track of how many collectable items are remaining.
6. InEvent Begin Play, we need to find how many collectable items are in the map and then store this value
in the variable that we just created—RemainingCollectableItems. Therefore, we don't need to
worry about adding more collectable items during the level design phase since the Blueprint will
automatically calculate how many items the player has remaining to collect to open the Final Door. We

258
Final door (to somewhere)
can achieve this behavior by following these steps:
1. Dragging the output pin of the Event Begin Play into the Get All Actors of Class node and selecting
the Actor Class to be BP_ColletableItem.
2. From our Out Actors, get the Length of the array and store it in the RemainingCollectableItems
variable.
3. At this point, our graph should look as follows:

7. Now, create a Branch so that if the remaining collectable items are equal to 0, then it calls
the OpenDoor event. We are doing this in Event Begin Play so that if there haven't been any collectable
items since the beginning of the game, the door will automatically open. As a result, if there is a level
design mistake, the level will still be solvable. This is what the Event Graph should look like now:

8. Next, we need to provide a way for the collectable items to communicate to this Blueprint that they have
been collected. We can do this by creating another Custom Event and naming it Item Collected. Then,
259
Final door (to somewhere)
from here, we need to decrease the remaining collectable items by 1 and then create a branch for
checking whether the RemainingCollectableItems is at 0. If true, call OpenDoor again. Once you have
done this, the Blueprint should look as follows:

9. Optionally, you can insert a Print (before the Branch) of how many collectable objects remain for
debugging purposes, as shown in the following screenshot:

Compile, save, and close the editor.

260
Collectible items
Collectible items
Now that we have our Final Door ready, it is time to create our collectable items. In
particular, the to be able to detect when the player overlaps, collects them, and
communicates/notifies this to the Final Door. In this scenario, we are assuming that there
is only the Final Door.
However, feel free to change this mechanism as an exercise. To achieve this, let's go
through the following steps:
1. Open up BP_CollectableItem.
2. Let's add a Static Mesh component and call it ItemStaticMesh. If we select it, we can adjust its settings
in the Details panel. In particular, we need to assign a mesh so that our collectable item has a shape in
the world. Feel free to use any mesh that suits your needs the best. For our purposes, we'll use a sphere,
such as the FirstPersonProjectileMesh, which is provided in the First-Person template package. Don't
forget to scale it in the Viewport so that it is an appropriate size. Moreover, you can change the material
instance of the projectile. I went for a purple look, with a really high metallic value. You can see an
example of it within our game environment (which we will build soon) here:

3. In the Collision tab, change the Collision preset from BlockOldDynamic to OverlapOnlyPawn. As a
result, the player can overlap with the static mesh but everything else, such as our projectiles, will hit it
as a physical object. The following screenshot shows us what the final settings should be:

261
Collectible items

4. Now, always within the Details Panel of our ItemStaticMesh component, in the Events Tab, add the On
Component Begin Overlap event.
5. In the Event Graph, from the event that we have just created, let's check that the overlapping actor is
actually the player with a cast. If this is true, then we need to retrieve the Final Door (always assuming
that it is unique within the map) by searching for it by using the GetAllActorsOfClass node and setting
the Actor Class to BP_FinalDoor.
6. From here, we can just get the first element of the Out Actors array, since there should be only one Final
Door.
7. Using this reference, we can call the ItemCollected function to communicate/notify to the Final Door
that the item has been collected.
8. Finally, we destroy the collectable item using the DestroyActor function. Here, you could do something
fancier such as playing a particle system or sound, like we will see later on in this book.
9. This is what the final graph should look like:

262
Collectible items

263
Winning conditions
Winning conditions
Now, it is time to determine whether the player has succeeded in achieving what they
were supposed to do—that is, to ideally win! In our game, the player is going to win if
he/she reaches the end of the maze, after the final door (so the player has to collect all
the items first). However, in our game, even if the final door is opened, we need a way to
check when the player has actually finished the goal of reaching the end of the maze. We
can easily achieve this by using a trigger box, which will be placed after the Final Door.
Here are the steps you need to complete for creating such a trigger:
1. Create a new BP class of type Trigger Box in the gameplay elements folder and call it
BP_WinningTrigger.
2. Select the Collision component, and, within the Events Tab, add the OnComponentBeginOverlap event.

3. Like we did before for the collectable items, we check through a cast that the other overlapping actor is
actually the player. If it is true, we trigger a winning condition.
4. To keep things tidy, create a Custom event titled Won and connect the output pin to a print node to
display the following text: Congratulations, you have won!. Also, give the print node a color—we'll use
green here. Keep in mind that this is just for testing purposes because the print string is only available
within the editor and not within shipped games, so ideally you should load the next level and
congratulate with the player via the UI. We won't do any of this now since we already covered UI in the
earlier chapters. However, feel free to implement whatever you like as an exercise.
5. Lastly, call the Wow event after the check of the OnComponentBeginOverlap event. In this way, when
the player reaches the trigger, the Won function is called.
6. Once you have done the preceding steps, the event graph will look as follows:

264
Winning conditions

265
Destroying the AI
Destroying the AI
Unreal has a built-in damage system, which is very abstract and powerful at the same
time. It's abstract in the sense that it has no concept of hit points or death (it lets you
specify these entities within your game), but powerful because it allows you to quickly
implement different damage types, extend the system, and build upon it very quickly.
However, this is pretty much overkill for our needs, so we'll just implement our own
simple damage system for ourselves. Follow these steps to get started:
1. Open the Third-Person Character (our enemy) and add a new public variable. Call it Health, of type
Integer, and give it a default value of 100. Remember that to assign a default value, you need to
press Compile first.
2. Create a DieEvent node. From here, we can implement any fancy death for our AI character. So, feel
free to use your imagination. For example purposes, we'll keep it simple and just destroy the AI
character. Later, we will see how to connect this death with the spawning system.
3. Next, let's create a Custom Event and call it ProjectileHit. Add an integer named Damage as
input. This will be the way that our projectile (in the next section) will be able to communicate how
much damage the enemy took.
4. Then, we subtract the damage amount we received as input from the health variable and save the result
back into the Health variable. This is the de facto part in which the enemy is taking damage.
5. However, we still need to check whether the AI has run out of health. Therefore, if the Health variable
reaches 0 or below (you cannot check if it is equal to zero because the damage could bring the health
below zero, and in this case the equal statement would be false; alternatively, you can clamp the health
before the check), then we call the DieEvent.
6. This is what our event graph should look like:

266
Destroying the AI

Now, the enemy AI is able to receive damage, but there is nothing in the game (yet) that's
able to deal damage to the enemy. As such, let's modify the projectile that the player
shoots to deal a random damage to the enemy (only if it is hit, of course!).
Go to FirstPersonProjectile (Content | FirstPersonBP | FirstPersonProjectile) since we
need to add two public integer variables, which will represent the random damage range
that the projectile can inflict to an enemy:
One called MinDamage, with a default value of 3
The other one called MaxDamage, with a default value of 15

The fact that you have these two variables allows you to create different projectile types
(for example, different damage stats).
As you will have noticed, the Event Graph will already have an Event Hit event node
connected to a part of the graph, commented as At Physics Impulse To Any Physics
Object We Hit. You can see an example of this in the following screenshot:

267
Destroying the AI

Between the event hit and the rest of the graph, we need to insert our code for damages.
In particular, from our Event Hit, we need to check whether we hit an AI character:
If No (the cast failed), we connect that branch to the rest of the graph that we had before (see the
following screenshot)
If Yes, we add our own code

In particular, we create a Random Integer in Range node and we plug the Min and Max
damages as inputs. An example of this is shown in the following screenshot:

268
Destroying the AI

Then, as a Third-Person Character (from the cast), we call the ProjectileHit event and as
a damage, we insert the result value of the Random Integer in the Range node. As a
result, this projectile will damage the AI enemy. Finally, we will destroy the projectile,
since once it has hit, it needs to disappear. Optionally, you can use the Print node for
displaying how much damage each projectile inflicts to the enemies for debugging
purposes. This is the final graph:

269
Destroying the AI

This is all well and good, but if we were to test the damage system now, we would soon
realize that the projectile passes through the enemy without even a scratch. This is not a
bug, but a setting! In fact, the selected collision preset of the project does not hit pawns
(including our AI character). Thus, we need to change the preset in the following way:
1. Select the Collision Component and under the Collision tab, expand the collision presets.
2. Here, there should be a table of checkboxes. We need to stop the pawn row (of the table) from ignoring
to block.
3. This is what the setting should look like in the details panel:

270
Destroying the AI

Finally, compile, save, and close the Blueprint. We can hit the Play button and test that
we can actually destroy our AI character as planned.

271
Creating a spawning system for our enemies
Creating a spawning system for our enemies
Now, what happens when we destroy an enemy? They have to come back somewhere,
right? Well, to our perhaps disliking, the answer is yes, because no game was ever
enjoyable without some level of conflict.
As our game goes, the goal of the player is to survive the maze and reach the end. Killing
an enemy is just a useful way to temporarily get it out of the way. I underline temporarily
because as soon as the player kills one of the enemies, another one is spawned to a
random location within the maze. To be more precise, there will be some spawn points
around the map that the level designer can carefully place, and the AI will respawn in one
of this location at random.
To begin our journey to respawn our fallen nemesis, we need to follow these steps:
1. In the Game Elements folder, create a Blueprint class that derives from Target and name it
BP_SpawnPoint.

The start of the spawning system can be coded inside the Game Mode, which in
some way defines the rules of the game. We will not go into detail about how the
Game Mode works—at least not in this project—but we will use it to define the
spawning system. In particular, we already have FirstPersonGameMode inside our
project, inside the Content | FirstPersonBP | Blueprints folder, so let's
open it and click on Open The full Blueprint Editor.
2. In the Event Graph, create a custom event and call it SpawnNewEnemy.
3. From the output pin of the event, drag out the Get All Actor Class node and select BP_SpawnPoint as
the Actor class. As a result, we will be able to get all the Spawn points in the map. In fact, we want to
spawn an enemy in one of these points at random.
4. From the Out Actor pin, we will retrieve the Length of the array (which indicates how many spawn
points there are) and plug the result into a Random Integer node. This will allow us to choose a random
number between 0 and the number of spawning points. As a result, we can choose a Random Spawning
Point.
5. From Out Actor, we will retrieve this Random Spawning Point, and from here we get the Actor
Location. We are basically selecting a random point within the array and we are retrieving the position
of that random spawn point.

6. Now, from the Get All Actors Of Class node, we will drag this from the output pin into a Spawn AI
From Class node. Then, we will select the Third-Person Character for the Pawn class and plug the Get
Actor Location result into the Location pin on the Spawn AI From Class node. This is what the code
looks like so far:

272
Creating a spawning system for our enemies

We have finished the spawning system—it's very simple. As an exercise, you should
check that the array has at least length one, and if it doesn't, you should launch a warning
and not spawn any AI.
However, when an enemy dies, the spawning system does nothing because we need to
call the Spawn New Enemy event when an AI dies. To do so, we need to follow these
steps:
1. Open the Third Person Character Blueprint.
2. We need to change the default AI controller class. As you may remember from the previous chapter, we
have selected the right controller, but just for the character that was already in the game. By changing
the settings in the Blueprint, we will ensure that every character that we spawn will get the same AI
controller. All this achieves at the moment is getting the AI to wander around the ma. Therefore, change
the AI controller Class to BP_AIController. This is what it should look like in the Blueprint:

273
Creating a spawning system for our enemies

Then, in the Die custom event, after Destroy Actor, we will place the Get Game Mode node and cast it
into the First-Person Game Mode. If the cast succeeds, we call the SpawnNewEnemy function from the
First-Person Game Mode. As a result, after an enemy dies, another one is spawned. Once you have done
this, your code should look like as follows:

274
Creating a spawning system for our enemies

You can now compile, save, and close the Blueprint editor.
Now, in the map, place some AI characters and as many spawn points as you
like. Finally, press the Play button and test your gameplay. You should see that when an
AI enemy is killed, it respawns at one of the respawn points.

275
Restarting the level
Restarting the level
Before to move on to the next chapter, we need one more thing. In fact, when the player
dies, we need to restart the level. However, we will test this function later in this book,
but for mental order, it is better than we write it down now. We can do this very quickly
by adding some code to the Game Mode:
1. Create a new Custom event named RestartLevel.
2. Play a fancy game over. In our case, we can spawn fire that's attached to the player (which will simulate
the screen being engulfed in fire).
3. We delay some seconds so that the player can enjoy or hate our fancy game over fire.

4. Finally, we restart the level by opening it again. This is what the final code should look like:

As you can see, the name of the level is hard-coded (which means that it is not inside a
276
Restarting the level
variable that can be easily changed, but within the code; this is usually a bad practice
because it becomes hard to find and change). As an exercise, try to modify the code so
that it only restarts the current level that the player is playing.
Interestingly enough, the Game Mode already has an inherent function for resetting the
level named Reset Level, which can be overridden. You can try to override that one to
try and Reset your level as an additional exercise.

277
Extending upon what you've&#xA0;learned&#xA0;here
Extending upon what you've learned here
Now that we've had a look and a play around with Behavior Trees and Blackboards, it's
time to extend our knowledge with some exercises. Here, I have suggested a few
activities for you to try out that will challenge what you have learned here. Keep in mind
that, in some cases, you may have to do a little bit of research on your own to complete
these challenges, but they do not require that you learn a great deal more than what we
have covered in this chapter:
Even though win and lose are the most typical gameplay states, can you think of any others? For
example, what happens when both the player and the enemy win or lose and it becomes a draw?
So far, our Final Door just disappears. Based also on what you have learned from our past project, try
to implement this behavior for the door. Once all of the items have been collected, the door is in a state:
as soon as the player gets close (so that the player is able to see this happening), the door will slowly
open.
After so many challenges, the player is rewarded with a simple message. I'm not asking for fireworks,
but you could try to experiment with different ways to reward the player.
When we spawn a new AI Enemy, the code doesn't check if there is at least a spawning point in the
array. Perform this check, and if none are available, don't spawn the enemy and display a warning
message.
It wouldn't be nice for the player to kill an enemy and then find it respawned just at his/her back. Try to
change the code so that the spawning point is not next to the player (for example, if the point is too close
to the player, try another point; alternatively, sort the spawning points and decide which ones are good
to go).
At the moment, we have the name of the level hard-coded in our Restart Level function. It would
be nice to improve the code and remove this limitation.
If you want to go a step further and explore the features of a Game Mode, try to implement the
Restart Level function as an override call to the inherit Reset Level function.

278
Summary
Summary
We've reached the end, but let's take a moment to look at what we've achieved. So far,
we have learned how to create in-game scenarios where AI enemies are destructible. In
addition, learned how to create a respawn system for the player, as well as enemies and
items. Next, we defined gameplay conditions, which determined whether the player wins
or loses. Lastly, we learned about creating game states for when the player wins or loses
(for example, from dying). With this and everything else that we have learned so far, it is
time to begin learning about how to make our game environments more immersive.
In the next chapter, we will look at how to create complex AI systems that make the AI
more receptive to the player and their location. In addition, we will also learn how to
create personalized tasks, decorators, and conditions so that the AI will respond to the
player in a particular way (for example, run toward the player). Lastly, we will look at
how to make the AI chase and attack the player (continue to follow the character as long
as they are in sight). So, what are you waiting for~!

279
Upgrading the AI
Upgrading the AI
Here we are again. But this time, we are going to create an AI that wanders at random
until it finds the player. Once it finds the player, it will chase them down, and if it loses
sight of the player, it will try to reach the last known position of the player. If the player
is still not found, it will revert back to its wandering behavior. The way that we can
achieve this can be done in different ways, but we are trying to do it in such a way that
you can learn how to make custom tasks, Decorators, and Services work together
properly. Therefore, in this chapter, we'll cover the following topics:
How to create complex AI systems that make the AI more receptive to the player and their location
Creating personalized tasks, Decorators, and conditions so that the AI will respond to the player in a
particular way (for example, run toward the player)
Make the AI chase and attack the player (continue to follow the character as long as they are in sight)

Of course, these may seem like simple actions and interactions, but they will provide the
foundation to many different experiences that we will not just create within this book, but
also throughout our careers as game developers.
The following is a quick overview about how we are going to create our AI (this is not the
only way we could do this, but it is a way that tries to explore a bit of all the aspects so
that you can learn about all of them):
1. We will start by using the perception system that's built into Unreal. This system will equip our AI with
the sense of sight, so it will be able to perceive actors around it, and in particular the player.
2. We need to set some variables in the Third Person Character every time the Perception Component
updates.

3. We then need to run a Behavior Tree under a service, which copies the variables in the Third Person
Character inside a new Blackboard (that we will create).
4. Then, the Behavior Tree will be split in two, depending on whether the AI is able to see the player in
that moment or not. If yes, then the AI will chase the player. If not, the AI will first try to reach the last
known player location (of the AI) before resuming random wandering behavior.

280
Equipping our AI with sight
Equipping our AI with sight
Now that we have our AI doing what it wants or taking orders, it's time to give it an
upgrade. Now, what do we mean by upgrade? Well, for one, we want to make it respond
in a particular way. This also means to respond defensively toward a character or have
their behavior alerted when a player comes within range of them. For example, we can
use environmental cues to trigger them to respond to a player. To do this, we need to set
up a few things.
To begin, follow these steps:
1. Open up the Third-Person Character Blueprint.
2. To give the AI some kind of perception, we need to add a component—more specifically, AI Perception
(Add Component | AI Perception). This component will keep track of which agents (including the
player) the AI can perceive. The component implements many senses, but for now we are only
interested in sight. However, this component needs to be properly configured.
3. Select the AIPerception component we have just created and in the Details Panel look for the AI
Perception tab, in which we can add which kind of perception this component implements. Since we
want the sight sense, let's add a Senses Config of type AI Sight Config.
4. If you expand the menu down (twice—look at the following screenshot to help you out), you will see the
specific settings for the AI Sight perception. The Default values are fine, but feel free to tweak them as
per your needs. The two most important parameters are as follows:
The sight radius: How far the AI can see/detect the player
Lose sight radius: The distance at which the AI loses sight/detection of the player after they have
already been detected

5. Before moving on, we need to select all the Detection By Affiliation flags. In fact, by default, every
agent and pawn are neutral to each other. You can change the player so that they are detected as an
enemy, but that would involve some C++ code. At the time of writing, it isn't possible to set a team in
Blueprint. Therefore, if we set all the Detection By Affiliation to true, we will be sure to detect our
player. A downside to this approach is that you will need to filter your perception results to distinguish
your player from the other agents (for example, the AI), but it is not a big deal, especially since we are
implementing everything in Blueprint and we don't have many agents in our game!
6. In the end, you should have you perception component that looks as follows:

281
Equipping our AI with sight

Now that the perception component is up and running, we need to use it to check
whether the player is in sight, and if so, where they are. As per design, we just need to
store this information within the Third Person Character, and then the Behavior Tree will
retrieve this information for itself later on. To store such information, we need to go
through the following steps:
1. In the AI Perception component, under the Events Tab (in the Details Panel), click on On Target
Perception Update Event. This event will fire every time the Perception Component starts or ends to
282
Equipping our AI with sight
sense something, which makes it perfect for our needs.
2. The next step is to set some variables in the third-person character that will be retrieved later on from
the Behavior Tree. Optionally, you can set their category to AI to keep your project tidy, but this is
optional. So, let's add three new public variables:
Type vector: Named Last Player Location, which will hold where the player was seen last
Type first-person character: Named Player Reference , which will contain a reference to the
player object
Type bool: Named Can See Player, which will determine whether the AI can see the player or not
3. This is what they look like in the editor:

4. To set these three variables, let's cast the Actor pin on the On Target Perception Update Event to a
First Person Character. This will allow us to check whether the perception is about the player and if
so gather some data.

5. Then, store the result of the cast in the Player Reference variable.
6. Next, from the Stimulus pin of the On Target Perception Update node , connect it to the Break AI
Stimulus. This will allow us to have access to the Stimulus information. In particular, there is
Successful Sensed, which we can set inside our Can See Player variable. This will tell us whether the
player has just left our field of view or not.
7. After this, we can create a branch, with the condition of using the Can See Player bool variable. If the
condition is false, then it means that the AI just lost sight of the player, hence we set the Last Known
Player Location to the Stimulus location. In this way, the AI has the concept to know when the player
was last seen.
8. Finally, this is what our code should look like:

283
Equipping our AI with sight

Now, before we move on, there is one last change to make. In fact, the AI will be way
too fast, especially when it chases the player since the default value is too high. To fix
this, select the Character Movement Component and change the Max Walk Speed to
250. Feel free to set a number that better suits your game, though.
Lastly, save the Character blueprint and close the editor.

284
A Blackboard full of data
A Blackboard full of data
We need to set up a few bits and pieces so that our AI has a memory of what is
happening and where the player is (and what to do when they do encounter the player).
First, we will need to create a Blackboard with a few keys:
1. In the AI folder, create a new Blackboard and name it BB_ChaseBehaviorBlackboard. This
Blackboard will contain all the information we need to achieve our chase/wander behavior.
2. Next, we need to add the following keys:
Type Bool named Can See Player. This variable will be used to determine whether the AI is able
to see the player. However, as you will see later on, we will not use its values (true or false), but
rather if its value is set in the Blackboard. We will assume that when this variable is not set, then
the AI cannot see the player. On the other hand, when this variable is set to true, then the AI can see
the player. As per design, the variable should never assume that the value is false, at least for the
use we are going to do in this chapter.
Type Vector named Random Destination. Easily guessed from the name, this variable will store
a random location that's used during the wandering behavior. As we will see later on, we will
check if this variable is set or not to change the type of behavior. In particular, if the player is not
seen, then we will determine whether the AI should go the last known player position (Random
Destination is not set) or if the AI has already checked that place and resumed its wandering
behavior (Random Destination is set to a random location).
Type Vector named Last Known Player Position. Again, this variable stores the last known
position of the player for this agent.
Type Object (with Base Class set to First Person Character—you will need to expand the menu to
do this) named Player Reference . This variable holds a reference to the actual Player object in
the game. Since during the chasing phase the AI has to continuously try to reach the player, we need
a reference to the Player itself so that they smoothly chase after him/her.

3. Save the Blackboard. This is the end result:

285
A Blackboard full of data

286
Creating a chasing behavior
Creating a chasing behavior
What is more enjoyable than being chased by something other than, well, anything! It is
an essential part of any game, which requires that our skills are refined and that our
reflexes are quick. So, let's add a little bit of excitement to our game by making the player
engage in a bit of hide-and-seek!
1. Create a new Behavior Tree inside the AI folder and named it BT_ChaseBehaviorTree.
2. Open up the Behavior Tree editor and set BB_ChaseBehaviorBlackboard as the Blackboard.
3. From the Root Node, place a Selector Node since we will either be able to see the player and
therefore chase them, or not. However, while we are executing this, we need to continuously update
some values such as if the AI is able to see the player. Therefore, this is the perfect job for a Service . In
fact, a Service is continuously executed as far as the execution of the Behavior Tree is within one of its
children.

287
Updating values with a Service
Updating values with a Service
At this point, we need to start updating the values by using a Service. To do this, we need
to do the following:
1. From the top bar, click on New Service and rename it (in the Content Browser) to
BTService_UpdateValues.
2. Open up the Service in its Blueprint editor.
3. We need to add three public variables (see the following screenshot), all of the type Blackboard Key
Selector, named as follows:
Can See Player Key
Last Known Player Location Key
Player Reference Key:

4. Then, we need to override (remember that next to the functions there is a dropdown menu called
override) the Event Receiver Tick AI function so that we can update all of the values within this event
call. This function is called periodically, so it is perfect for updating our values continuously.

How often the Service performs a Tick (its Tick function is executed) can be decided
within the Behavior Tree. Moreover, it can be a random time between two values. The
default values are a minimum of 0.4s to a maximum of 0.6s.
5. From the output pin of the Event Receiver Tick AI function, cast the Control Pawn to Third-Person
Character and as a Third-Person Character. As a result, we will be able to use this reference to the AI
Character so that has access to the variables we saw previously.
6. In particular, we need to retrieve the Can See (Bool) variable and branch on its variable:
if True we use the Can See Player Key to set its Blackboard Value As Bool to True
Otherwise, if False , we use the Can See Player Key to Clear Blackboard Value
Either way, we continue our logic flow into the same Node

7. So far, this is what our Service looks like:

288
Updating values with a Service

8. Now, we use the Last Known Player Location Key to Set Blackboard Value As Vector to the value of
Last Known Player Location, which is retrieved from the Third-Person Character reference.
9. Finally, use the Player Reference Key to Set Blackboard Value As Object to the Player Reference
variable that's retrieved, as always, from the Third-Person Character. Once you have done this, you
will have something that looks as follows:

289
Updating values with a Service

10. Next, go back to BT_ChaseBehaviorTree , right-click on the Selector, and select Add Service… |
BTService Update Values.

11. Now, if we select this Service, in the Details Panel, we can set its variables (as shown in the following
screenshot), in particular:
Can See Player Key to Can See Player
Last Known Player Location Key to Last Known Player Location
Player Reference Key to Player Reference:

290
Updating values with a Service

12. So far, we should have the tree that looks like this:

291
Using Decorators
Using Decorators
1. Now, from the bottom of the Selector, add two Nodes:
A Sequence (on the left)
Another Selector (on the right)
2. On both Nodes, we need to add a Decorator. Right-click Add Decorator... | Blackboard to do so. This
kind of Decorator checks whether a specific variable in the Blackboard has been set. This is the reason
why, before, while creating the Blackboard, we said to use the information about whether or not the
variable is set as an extra piece of information, and thus we reflect on this when our variables are
updated in the Service. However, the point of these two Decorators is to divide the tree into two
branches—one that will follow the chasing behavior and another one that will check the last known
player position before resuming its wandering behavior.
3. On both Decorators, we need to change (in the Details Panel) the Observer aborts to Self, as shown
in the following screenshot:

The reason why we changed this setting is because, as soon as the condition of
the Decorator changes, we want to abort all the branches (stop doing what the
AI was doing, such as wandering) so that the AI meets the new condition (for
example, the player is seen, so it stops it wandering behavior to start chasing the
player).

292
Using Decorators
4. Next, change the Blackboard Key to Can See Player. Of course, this condition to meet is if the AI is
able to see the player, which is encoded regardless of whether the Can See Player variable is set or
not.
5. However, on the right Decorator (above the Selector), we also need to set the Key Query to Is Not
Set. In fact, if we want to perform the chasing behavior (on the left) when the AI sees the player, we
want to execute the behavior on the right when the AI is not able to see the Player.
6. This is what the tree should look like now:

293
Creating the chasing task
Creating the chasing task
Now, we need to get the AI to actually chase the player, or at least, tell the AI what to
do when the player comes within their field of view. To begin, follow these steps:
1. Let's create a New Task (in the top nav bar) that derives from BTTask_BlueprintBase . In the Content
Browser, we can rename this to BTTask_ChasePlayer.

2. Now, open up the task and add three variables of type Blackboard Key Selector:
Player Reference Key
Can See Player Key
Random Destination Key
3. Next, override the Event Receive Execute AI Event, and use the Random Destination Key to Clear
Blackboard Value. As a result, we are un-setting the random destination. This, as we will see, will
result in the AI first trying to get to the last known player location before resuming the wandering
behavior.
4. Then, we connect the output pin of the event into an AI Move To Node. Here, we need to connect the
Controlled Pawn pin from the Event to the Pawn pin of the AI Move To. This will result in allowing the
controlled pawn (the AI character that is running the Behavior Tree) to move to a certain location.
5. This is what the graph looks like so far:

294
Creating the chasing task
6. Now, use the Player Reference Key to Get Blackboard Value As Object and cast it to the First Player
Character (convert the cast to a pure Blueprint for convenience—you can do this by right-clicking on the
cast Node and selecting Convert To Pure Cast) and plug the result into the Target Actor pin of the AI
Move To Node. As a result, the AI will smoothly chase the player while it is executing this task.

7. From the On Success pin ofAI Move To, we can trigger the Losing Conditions of the player (that we
implemented in the Game Mode in the previous chapter, which in this case is triggering to restart the
level). If you are sure that that the level is going to restart, there is no need to finish the task with a
success. However, if you are not sure, then finish executing the task with a success. Optionally, we can
print a log that the AI has won for debugging purposes.
8. From the On Fail pin of AI Move To, we need to return that the task has failed. We do this because,
ideally, we are building tasks that are suitable for different Behavior Trees. In this particular one, we
checking to see that if the player is still in sight, then the Behavior Tree will try to re-execute this task
again. For example, the AI Move To might fail because the player jumped off a cliff and temporarily
wasn't on the nav-mesh.
9. You can see an example of this in the following screenshot:

295
Creating the chasing task

10. Save the task and head back to the Behavior Tree. From the Sequence on the right, add the tasks we
have just created. This is the resulting tree (if yours doesn't look like this, remember that you need to
make the variables inside the Service and Task public):

296
Creating the chasing task

297
Moving to the last player position and the wandering behavior
Moving to the last player position and the wandering
behavior
At this point, we want the player's last position to be recorded by the AI so that they have
an idea about where they should head toward, or if they can no longer find the player, to
wander (albeit aimlessly) around the environment until they encounter the player. We'll
cover how to do this in the following steps:
1. From the Selector on the right, drag two Sequence Nodes. One will lead to the behavior of getting to
the last player position, while the other one serves to wander.
2. On the Sequence Node on the left, add a new Decorator of type Blackboard like the previous ones and
set the following:
Observer aborts to Self
Key Query to Is Not Set
Blackboard Key to Random Destination
3. This will ensure that as long as the Random Destination variable is not set, the AI should do everything
below this Node (that is, get to the last known player position).
4. Now, from this Sequence Node, we drag a Move To Task and set the Blackboard Key to
LastKnownPlayerLocation. This will actually move the AI toward the last known player position.
5. Then, again from the same Sequence Node, we drag the BTTask_RandomLocation (which we created
in Chapter 7, Reducing Loneliness with AI) and set the following:
Location to Random Destination
Radius to 600
6. In fact, in case we've already reached the Last Known Player Position, then we set the Random
Destination key (which will stop the AI from executing this branch), making the other branch the only
one that's available (the wandering behavior). This is what the tree looks like so far:

298
Moving to the last player position and the wandering behavior

7. Finally, from the second Sequence Node from under the Selector, we drag a
BTTask_RandomLocation, using the same settings as before (you can even increase the radius if your
map is big, that is, unless you don't want your AI wandering around).
8. Then, drag a Move To Node with Blackboard Key set to RandomDestination.

9. This completes also the wandering behavior, as well as our tree. This is what the overall tree looks
like:

299
Moving to the last player position and the wandering behavior

300
Executing the Behavior Tree
Executing the Behavior Tree
Before we continue, let's save the Behavior Tree and close the editor. So far, it's amazing
that we have a whole Behavior Tree for chasing the player. However, if we press play,
we will still see our AIs wandering and nothing more. The problem is that they all use the
BP_AIController, which we created back in Chapter 7, Reducing Loneliness with AI,
which starts the simple wandering tree. To fix this, follow these steps:
1. Open the BP_AIControlle r and change the BTAsset of the RunBehaviorTree Node to
BT_ChasedBehaviorTree.

2. Once you have done all of this, you will have something that looks as follows:

Compile, save, and close the editor. It is now time to test if everything works as expected,
and hopefully, if you have followed along, it should. By now, you should have all the
core game functionalities working, so mess around with it for a bit. Actually, it is almost a
complete game. Really—have serious fun with your own creation before moving on; this
turned out to be quite an interesting game!

301
Extending upon what you've&#xA0;learned&#xA0;here
Extending upon what you've learned here
Now that we have finished this chapter, we can start thinking about ways to add all of
these elements together. The following are several exercises that I encourage you to test
out:
Try to implement the hearing perception of the AI by using the AI Perception component
Try to create your own AI behavior by using custom Services, Tasks, and Decorators. Practice makes
perfect, so the more you practice, the better you will be

302
Summary
Summary
We have covered quite a lot in this chapter. We have not only learned how to improve
the AI within our game but also how to make it a lot more perceptive and responsive
toward our player. We have achieved this by extending upon our knowledge from earlier
parts within our book. We have learned how to make the AI observe the player and then
continue to chase them for as long as the player remains within sight. We have also given
our AI a bit more autonomy to continue exploring the environment in search of the player
once it has lost sight of them.
Next, in Chapter 10, Adding Audio, we will learn about how Unreal handles audio files
and more importantly how to use audio in our game. We'll add some basic atmospheric
audio to our project, but you'll be equipped to turn this into something much more than
something that's basic. So, take a quick break, turn up your speakers, and get ready to be
immersed in a somewhat sensory adventure! It's time to turn the volume up and head
over to the next chapter.

303
Adding Audio
Adding Audio
Sound can create an engaging sensory experience that can build tension to articulate and
convey emotions. It is also one of the most essential parts of a game's environment.
Moreover, since we cannot physically be within the game world (at least not yet), nor
taste or smell it, most of us are able to hear or see it. Therefore, beyond seeing the game
environment, the only other sense that we can utilize is hearing, so it should be
considered in great detail when creating your game.
In this chapter, we'll cover the following topics:
Using sounds as part of the game experience
Importing sounds in UE4
Using the Sound Cue Editor
Adding audio into the project
Creating triggered sound events

Even though these things seem quite simple, they provide the essential foundations for
building more complex and immersive aural experiences for the player, which, along with
well-structured gameplay, a solid narrative, and mesmerizing environments, help to
provide the perfect gaming experience.

304
The use of sound in games
The use of sound in games
The use of sound within a game can vary depending on the intended purpose. For
example, we may use sounds to alert the player that something has happened, such as
triggering an alarm. We might also use sound effects for when players interact with
different parts of the game environment or even the UI.
In these cases, sound provides a sense of feedback in the way of cause and effect; the
player performs an action and this action is confirmed with a noise. Last, but not least,
sound can be used to create an atmosphere, from a catchy soundtrack while you're racing
through the jungle being chased by a tiger, exploring bazaars full of people and colors, or
exploring mysterious ruins. The point here: do not underestimate the power that sound
can have on a game's environment.
Fortunately for us, Unreal has an awesome sound-editing system, and importing, placing,
and setting up audio within our game is quite straightforward. We will cover the process
in the next sections. One last thing: all the sound files that we will use in this project can
be found at www.freesound.org.

305
The basics of sound in Unreal
The basics of sound in Unreal
Before we start importing or trying to import, audio into our game, there are a few things
that we need to consider when it comes to making sure that the audio files will work with
our project.
At present, UE4 suggests the recommended sample rate of audio files is between 44,100
Hz to 22,050 Hz. In addition, we can only import the .wav file format, so files that are
perhaps .mp3 or .ogg will need to be converted or rerecorded in the .wav format
before they can be imported in UE4. Audio bitrate should be at 16 bits and UE4 supports
speaker channels from mono to 7.1. Therefore, you have the ability to really utilize the
separate channels to create a truly immersive experience.

306
Sound asset types
Sound asset types
The following are a few different sound asset types:
Dialogue Voice and Dialogue Wav: These both are used to generate in-game dialogue events.
Examples include crafting subtitles and localization (changing the language that characters converse in
along with the subtitles).
Reverb Effects: Think of when there are announcements in a football stadium, which are often
followed by an echo. This is the reverb effect.
Sound Attenuation: Allows us to define the attenuation properties. If you want to learn more about the
technical properties of sound attenuation, check out the official documentation here:
https://docs.unrealengine.com/en-US/Engine/Audio/DistanceModelAttenuation.
Sound Class: is a collection of different properties, which can be applied to various sound assets.
Sound Cue: The behavior of audio playback in UE4 is defined in Sound Cues. Therefore, the audio
output (of the combination of) nodes, which is created in the Sound Cue Editor, is saved as a Sound
Cue.
Sound Mix: Allows you to set the Equalizer Settings (EQ) settings. In addition, it also allows you to
modify other attributes such as the Volume and Pitch properties of Sound Classes.

307
Adding audio into the project
Adding audio into the project
So, now we have some awesome audio that we would like to implement in our game.
When we import a sound file into UE4, it will generate what is known as a Sound Wave
asset. This can then be directly placed into a level or used to create a Sound Cue, which
can be edited inside the Sound Cue Editor (which we will discuss in the next section).
To import our audio into our project, we need to do the following:
1. In the Content Browser, click the New Asset button. Alternatively, you can also right-click in an empty
part of the Content Browser to access the New Asset menu.
2. Under Import Assets, click Import to the folder that you will store your audio files. In our case, we'll
create a new folder and call it Audio.
3. In the Import dialog box, locate and select the (.wav) file that you would like to import into your
project, and click Open. Once you have done this, UE4 will then import the file as a Sound Cue asset.
From here, this asset can be edited by using the Sound Cue Editor.

Alternatively, if you want to create a sound within the Sound Cue Editor, you can create
an empty Sound Cue asset by clicking the Add New button in the Content Browser and
then select Other Assets | Sounds | Sound Cue.
In this section, we will begin to learn about the foundations of the Sound Cue Editor in
UE4. The Sound Cue Editor is similar to Blueprints in the sense that it is a node-based
editor, which is used to work with audio inside of UE4. There are many different options
that will allow us to create a wide range of effects that can add additional atmosphere to
our games. We will explore some of these in this and the next project in this book.
If you're interested in learning more, you can check out the Sound Cue Reference
at https://docs.unrealengine.com/en-us/Engine/Audio/SoundCues/NodeReference.

308
Adding environmental (ambient) audio
Adding environmental (ambient) audio
Now let's add some tension, drama, or even happiness to spice things up a bit. For our
example, let's create something a little Halo-inspired. For this project, we will add a piece
of soft ambient music. We will use the looming abyss.wav file, which you can download
from https://freesound.org/people/ProtoSounds/sounds/379020/.

309
Attenuation
Attenuation
In the editor, these show us how far (the radius) we can hear the sound, and where (if at
all) sounds may overlap. However, there are many other types of objects that can also be
used for sound attenuation (box, capsule, and cone). You can find out more by
visiting https://docs.unrealengine.com/en-US/Engine/Audio/DistanceModelAttenuation.

310
Adding a box trigger to trigger (ambient) audio
Adding a box trigger to trigger (ambient) audio
In a lot of adventure or exploratory games, when you enter different parts of a map, they
can often change significantly in terms of atmosphere. For example, when playing is
running through the woods, they might hear birds chirping, wolves howling, but as they
begin to move closer to a lake or a waterfall, the atmospheric audio should adjust
accordingly. For example, they should hear the crashing of the water as it flows down the
rocks in a waterfall, or the splashing of water as a frog jumps into the pond. Therefore, it
is important that certain audio can be triggered when you enter different environments.
So, let's learn how we can do this!
For the purpose of our game, we want to trigger a darker area by overlapping a more
sinister audio track. For this, we will use the horror game ambience.wav, which you
can find at https://freesound.org/people/ofrm1/sounds/395672/.
Let's get started:
1. Import the .wav file for our triggered audio into UE4.
2. Add a Blueprint Class of the Actor type, call it BP_AudioDangerTrigger, and open it.
3. Click Add Component and select Sphere Collision so that we when entering the sphere, it will trigger
the audio file.
4. Add the audio file into the scene. Once you have done this, you will have something that looks like the
following image:

It is important to note here that you can also use static meshes to trigger sounds. To do
this, simply add the static mesh before adding the collision. Just make sure that the
collision mesh is large enough that the player can actually trigger it! For example, if
certain objects, such as flowers, trigger a particular sound effect, make sure that the
collision box/sphere and so on is larger than the object!
Now, we will begin to set up the Blueprints so that our audio is triggered as soon as the
player enters the Sphere Collison mesh. To do this, we need to perform the following
steps:
1. In the Event Graph, right-click and select On Component Begin Overlap.
2. Add the audio file to the Event Graph.
3. Drag the output pin from the audio file and select Play (Audio | Components | Audio | Play).
4. Drag the output pin from the On Component Begin Overlap and connect it to the input pin on Play.
5. Drag the audio file again into the Event Graph.
6. While dragging the output pin of the audio file, select Stop (Audio | Components | Audio | Stop).
7. Connect the output pin from Event Begin Play and connect it to the input pin of the Stop node.
311
Adding a box trigger to trigger (ambient) audio
Now, you could use triggers for a range of different aural experiences. For example, if a
player jumps into a bush or even a cart full of hay, a sound is triggered. The possibilities
are endless, and they are essential to consider if you want to create a truly immersive
environment.

312
Adding audio effects to various parts of the interaction
Adding audio effects to various parts of the interaction
Now it's time to create some triggered sound effects, such as when a player fires a
weapon, collects an item, and walks around the game environment.

313
Firing a weapon
Firing a weapon
By playing the game, you will have noticed that the firing sound is already present, and
every time that the player shoots, the sound is played. However, let's locate where in the
Blueprint code this happens, so in case you want to, you can change it.
Since the input of firing is handled in the FirstPersonCharacter blueprint (and we don't
have a very complicated weapon system), it is probable that the code is located there,
and actually, it is. Therefore, we need to find the Input Action Fire event and scroll to the
end of the graph, and there we will find our Play Sound at Location node:

Now, you are free to change it with another. In the end, you should see the parameter
changed:

314
Firing a weapon

Moreover, since it is a parameter of the Play Sound at Location node, you can handle it
as you wish. For instance, it can be a public exposed variable, or there might be a whole
graph on which sound to pick. On top of that, you can use the Cue Editor to add an even
more sophisticated system behind that single Play Sound at Location.

315
Collecting an item
Collecting an item
If we have been guided in firing, here on collecting an item we need to understand on
our-self where to place the code to trigger the sound.
As you may have guessed, we are going to do it in the BP_CollectableItem blueprint. In
particular, once opened, in the Event Graph, locate the end of the Begin Overlap event.
Between the call of Item Collected on the BP_FinalDoor and the Destroy Actor node,
you can place a node to play a collected sound. As before, you could use the Play Sound
at Location and choose as a location, the position of the Collectible Item, shown as
follows:

Alternatively, so that you can be aware of all your options, you can place a Play Sound
2D, which means that it is played regardless of the player's position. Usually, these 2D
sounds are used for UIs, but for your reference, here is the code:

316
Collecting an item

Don't forget to select the sound you chose, and you are good to go!

317
Expanding upon what you've learned here
Expanding upon what you've learned here
Now that we've covered the basics of audio in UE4, there are a few ways that you can
push and challenge what you have learnt.
Next time that you are playing a video game, pay attention to how the game uses sound. Does it use it in
the UI, environment, what about your footsteps? Do you make a noise if you knock something over? See
whether you can notice the similarities and differences between genres.
While you play a game, pay attention to how a player is provided with aural feedback. For example,
when you unlock a chest, do you hear the turning of the key and the creaking of the wood as you
discover ancient treasures? Perhaps there is a subtle sound effect that tells the player that they have
discovered something important or something dangerous, such as the rattle of a snake's tail.
Have a search on YouTube for game soundtracks from some of your favorite games. While listening to
them, close your eyes and imagine where you are; do you feel the atmosphere in terms of the tension,
fear, or happiness? Then find soundtracks to games that you haven't played and do the same thing, try to
sense the kind of atmosphere that they are trying to convey.
Try creating a small environment using asset packs from the Marketplace and then add to the atmosphere
using music.
Up for a challenge? Try creating four different regions within your map, one for each of the seasons
(summer, winter, autumn, and spring). Now, create atmospheric audio that helps to represent each of the
seasons. For example, the chirping of birds for spring, and the howling of wind and pouring of rain for
winter. If you really want to up the ante, you can also make these four sections blend seamlessly by
creating trigger boxes and by overlapping audio so that the transition between environments isn't a
shock to the player.
What would happen if the player cannot see? How could you use sound to indicate to the player where
they are or even how to navigate around the environment?
What about the Final Door? How could player the know that all the items have been collected and the
final door is opened? Maybe an opening door sound might help. Should it be 3D or 2D? Try it yourself,
and experiment with the different setups.

318
Summary
Summary
Just like that, the music fades away, but just for this chapter! So, let's look at what we
covered. We learned about how UE4 deals with audio and how to import it into our
project. Next, we added a bit of atmosphere to our environment using sound, which was
followed up with a few special sound effects.
In the next chapter, we are going to learn how to create dynamic materials. We will look
at how to create a material that can change based on different game conditions. We will
also cover the basics of particle effects; we will learn all about how to control pre-made
particle effects using Blueprints. Lastly, we'll cover lighting, where we will learn how to
trigger lighting effects using Blueprints.

319
Making It Pretty
Making It Pretty
Most people like to add a bit of razzle-dazzle into their lives, to make everything a bit
more exciting than the ordinary. Good news for you: that is what this whole chapter is
about! We'll look at a few different ways that we can add a bit of magic by creating
materials that can change as we interact with the environment to responsive lights as we
move around the environment.
In this chapter, we'll cover the following topics:
Dynamic materials where we will look at how to create a material that can change based on different
game conditions
Particle effects are where we will learn all about how to control pre-made particle effects using
Blueprints
Lighting where we will find out how to trigger lighting effects using Blueprints

320
Dynamic materials
Dynamic materials
For our environment, we want to create a material that we can interact with by
interacting with other in-game objects. For the purpose of this example, we will create a
material that will load/fill as we collect objects within our environment. Once we have
collected all the objects, the material will be complete. In this case, we'll have a large
statue in the middle of the map and as we run our environment collecting items, the
material for the large central statue will become complete. Actually, we will design the
system in such a way that we can place statues all around the map (and if you want, you
can still keep the big central one) so that the player can check their progress whenever
there is one of these statues.
You can see an example of this in the following screenshot:

And here another example in a different location:


321
Dynamic materials

And here's a third one:

322
Dynamic materials

We will build the amazing map you start to see in the screenshot very soon!

323
Creating the Filling Material
Creating the Filling Material
To do this, we need to begin by creating the dynamic material that loads as we go:
1. Create a new Material, and name it M_FillingMaterial inside the Materials folder (if you
don't have a Materials folder, you can create it).

2. By default, the material doesn't support transparency or opacity. So, in the Details panel at the bottom
left (under the Material Preview), you can find the General Material options. In particular, we need to
change the Blend Mode from Opaque to Masked and then check the Two sided option (since we want to
be able to see the material also from the inside out; therefore seeing the internal part of the material
through the parts that are hidden from the masked view):

324
Creating the Filling Material
A Masked material allows certain parts of the material to be masked (invisible), but it
doesn't allow different degrees of opacity (for example, certain parts of the material are
partially visible). For that, you need to use a different Blend Mode, such as Translucent,
but it is more resource-intensive. This means that it requires more computational power
and if you have a lot of them, it can slow down a project. For our purposes, Masked will
be more than fine!
3. Since we want to have some flexibility with the material, we can transform the Base Color, Metallic,
and Roughness input into parameters. You can do this by right-clicking on the input and
selecting Promote to Parameter:

325
Creating the Filling Material

4. Assign some default values for the three parameters we just created. For example, just a little bit
Metallic (0.3), high Roughness (0.79), and appropriate color for the Base Color parameter (for
example, purple). Remember that with a double-click on the square, you can open a color picker. In the
end, you should have something similar to this:

326
Creating the Filling Material

5. To let the Material be even more flexible, we can merge the Base Color with a Texture through a
Multiply node (by multiplying the pixels of the texture and our color, we can blend/merge the two). You
can add a parametric texture with the TextureSampleParameter2D node. Remember that it needs
a default value (and that's why it is created with a default texture at the beginning)! This is how the
graph should look at the moment:
327
Creating the Filling Material

If you want also a normal map, create another TextureSampleParameter2D which


will hold the normal map, and plug it into the normal input.
6. Let's work on the Mask of this material. We want the material to fill from the bottom up. So, we need
to identify the coordinates in the local space of the pixel that we are currently rendering. We can do this
by using the Local Position node:

328
Creating the Filling Material

7. With the use of a SplitComponents node, we can extract the single values of its coordinates. Remember
that a Vector in the Material Editor is a Color, even if it doesn't represent a color. In this case, it
represents coordinates/location. In particular, we need to get the Z-axis value which is stored in the
blue channel:

8. Discard all the pixels that are at a certain height. We can use the SmoothStep node, which will make
black (zero value) for an input less than its Min, and white (1 value) for input more than its Max. Since
we don't need the smooth part of the node, we can click on the Min and transform it into a parameter.
Name it FillingValue, give it a default value (for example, 0.5), and plug it into Max as well. As
Alpha, use the blue channel of the SplitComponents node. It might sound a little bit confusing, but here
is a picture to help clarify what it all means, and to show you how you should connect the different
nodes:

329
Creating the Filling Material

9. We need to invert the result of the SmoothStep node. In fact, we want white (1 value) at the bottom,
which means that it is not masked. On the other hand, we also want to cut off the top of our material. So,
we can use a 1-x node to invert the value. Finally, plug the result into the Opacity Mask input. This is
the final graph of our material:

330
Creating the Filling Material

10. This is how our Material should look in the Preview panel:

331
Creating the Filling Material

11. Close the Material Editor, right-click on the Filling Material, and select Create Material Instance (this
allows us to use the same material, but with different parameters; this is useful to quickly reuse a
material, but also increases the efficiency of the system rather than creating a different material for each
object). Rename it MI_FillingMaterial and open up the editor to change its properties.
However, don't worry about the FillingValue parameter, since we will derive that value from a
blueprint soon!

I hope that this gave you an understanding of how powerful the material editor is. So, if
you are interested in learning more about materials, I would suggest rereading about
material creation.

332
Creating the blueprint for the material
Creating the blueprint for the material
Now, it's time we create a new blueprint, which derives from the Actor class, in our
GameplayElements folder. We can rename it BP_FillingStatue. Once opened,
follow these steps:
1. Add a Static Mesh component, such as a sphere (or anything you like to show as an indicator of how
many objects the player is collecting). In our project, we will use the SM_Plains_Angel_Statue_01 as
our Static Mesh (which is inside the Infinity Blade Package we use for this project).
2. Change the Material (or the Materials) of this Static Mesh in MI_FillingMaterial. However, this step is
just to give you an approximate idea of the final result, because we will create Dynamic Material for
our Filling Statue.

In case you are not able to see the statue once the material has been applied, just change
the Filling Value in some higher value in the Material Instance. As a result, you will see
the statue to fill up.
This is because FillingValue is not relative, but it fills that amount (in Unreal units)
of the object on which the material has been applied.

It would be nice to get it relative in percentage directly into the Material, but since the
focus of this book is in blueprints, we will handle this issue in blueprints. However, you
are free to try to fix this issue in the Material itself (if you succeed, remember to remove
the blueprint fix we are going to create in just a few steps). Also, this is listed as an
exercise in the Expanding upon what you've learned here section at the end of this
chapter.
3. Create a Dynamic Material for our Static Mesh. In the Event BeginPlay event, let's create a new
dynamic material with the Create Dynamic Material Instance (static Mesh) node, using the Static Mesh
as Target and setting the Source Material to MI_FillingMaterial:

333
Creating the blueprint for the material

4. Right-click on the Return Value and select Promote to Variable. In this way, Unreal will automatically
create a variable of the right type for us, it will also place the correct Set node. The only thing you have
to do is rename the variable, for example to DynamicMaterial. This is how the graph looks:

5. Create a custom event named Set Filling Value, which will be fired from another blueprint. Add to this
event a float Input (in the details panel, click on the plus next to Inputs), which we can call
FillingValueInPercentage, which will contain a value between 0 and 1 (normalized value). This is
how our event looks:

334
Creating the blueprint for the material

6. Although it would be nice to directly set this percentage value directly into the dynamic material, we
cannot. In fact, as we did the material, the filling value is not in a percentage (or normalized to be
precise), but it is expressed in Unreal units (how many Unreal units we want the material to fill; the
convention says that 1Unreal Unit = 1 centimeter), and this changes from static mesh to static mesh.
We need to transform this percentage input value in a value in Unreal units, which the material can
correctly process. In doing so, we will need to determine how big the static mesh is. We use the
GetActorBounds node to gather the height of this blueprint in terms of Bounding Box (the box that
surrounds our static mesh, which we will use to determine how big the object is). If you right-click on
the Extend vector, you will be able to split the pins and save an extra node, so we can have direct
access to the Z-coordinate of the bounding extent. We take this value and multiply it
by FillingValueInPercentage.

However, since the Bound Extend is only half of the height, we need to multiply by
2. Another issue might be that this blueprint might have been scaled, and as a
result, it has influenced the overall value for filling the material. Therefore, from
the result of the multiplication, we need to dive by the Z-coordinate of the scale of
this actor. This is how the graph looks after all of these operations:

335
Creating the blueprint for the material

7. Set the resulting value into our DynamicMaterial by using the Set Scalar Parameter value node, use as
Parameter Name Filling Value (the same exact name as the parameter in the material):

336
Creating the blueprint for the material

8. Compile and save the BP_FillingStatue blueprint and integrate it with the rest of the gameplay. Call the
SetFillingValue event to correctly set the filling value as the player collects objects. The best place to
do so is BP_FinalDoor. In fact, this blueprint has accessed to all the collectible objects, so it
knows how many they are, and it is called every time an object is collected. Let's open up this blueprint.
9. Here, we could make the assumption that we are going to place only one BP_FillingStatue in any given
map, so it is easier to reference dynamically through the code. However, this time we will do something
different, and store a whole array of these statues, so if there is more than one, we are going to update
all them. In this way, we can place more than one of these statues, so that the player will be able to
check their progress from many different locations on the map.

10. We need two extra variables. One, named TotalNumberOfItems of type integer, will store the total
number of objects at the beginning (so we can express the filling value in percentage). The other one,
named FillingStatues, is of the array type (you can click on the little blue line next to it to make the
variable of the array type) and calls BP_FillingStatue, it will store the array of BP_FillingStatue:

337
Creating the blueprint for the material

11. Set the Total Number Of Items variable. We can change the Event BeginPlay and add this additional Set
node between the Set (for the RemainingCollectableItems) and the Branch node. We can easily use the
Total Number Of Items as value for the condition of the Branch node, which will keep our graph clean:

12. In the Event BeginPlay event node, set all the Filling Statues. Place a Get All Actor Of Class node just
as first instruction of the event, set the Out Actors into the Filling Statues variable, and then continue the
flow as it was before this change:

13. To keep our graph clean (you will see why in a couple of steps), let's create a new function to update
338
Creating the blueprint for the material
the statues, we can call this function Update Filling Statues. Once created, open up its graph, and let's
start by using a ForEachLoop on the FillingStatues array variable:

14. In the Loop Body, set the right filling value for each statue. In order to calculate this value, let's
transform RemainingColletableItems and TotalNumberOfItems into floats. Then divide, respectively,
the first by the second. As a result, we will have a percentage of how many items are still to be
collected, but we want the number of Items collected. Subtract one from this value to obtain what we
want. Plug the result into the Set Filling Value node (the event on the BP_FillingStatue), which uses the
Array Element as Target:

339
Creating the blueprint for the material
15. We need to place this function at the right moment. First of all, we want to be sure that all the statue in
the game is initially empty. In the Event BeginPlay, toward the end, just before the Branch node, update
all the statues by calling the function we just created:

16. We need to call our function every time we collect an Item. Let's call this function in the ItemCollected
event, after the Decrement (it is important, otherwise the Update Filling Statues will have old values of
the variable!) but before the Branch node, as shown in the following code:

17. Compile and Save the BP_FinalDoor blueprint.

Now, you will be able to place as many as Filling Statues you like in the level, and they
will automatically be filled in with the correct percentage, no matter the actual number of
items. Isn't Blueprint fantastic?
340
Getting LIT!
Getting LIT!
In this final part, we're going to look at creating some more dynamic lighting using
Blueprints. As we saw in chapter 1, we created some simple lights to illuminate the
environment. Now, we're going to create a light that is responsive to the player's location.
This means that the closer a player gets to a light, the faster it begins to change color. In
this example, the light will gradually change from red to blue and vice versa as the player
moves further away from it.

341
Light Mobility
Light Mobility
Before adventuring into creating dynamic lights, which are generated at real-time and
change many parameters, we need to first to understand Light Mobility.
If you select any light in your game (if at the moment you don't have one, just create
one), in the Transform section, you will see a parameter called Mobility:

This parameter is very important when you want to properly illuminate your game's
environment. Let's give a brief description of the three possibilities:
Static: This is a very cheap light (in terms of rendering performance), since it is baked into the
environment. It cannot cast dynamic shadows.
Stationary: A bit more expensive than Static, since it is baked, it also stores extra information that
allows to light dynamic object in real-time. However, it comes with many limitations, for example, it
cannot be moved.
Movable: This is the most flexible of the three options, but also the most expensive. It can cast shadows
in real-time, move, and change color and intensity.

If you are building Blueprint tools, it would be useful to check how Blueprint can control
all the types of light. However, in this book, we are dealing with Blueprint at gameplay
time. As a result, if we want to create and/or change the light, the Movable one is a must!
If you are interested in learning more about lighting, I suggest you check out books
specifically about lighting and level design.

342
Creating Dynamic Lighting in Blueprint
Creating Dynamic Lighting in Blueprint
As anticipated, we are going to create a light in real-time that will change color depending
on the Player's distance. Moreover, if the player is too far away, the light will turn off. To
create this, we need to do the following:
1. Create a new Blueprint that derives from Actor, and name it BP_DynamicLight.
2. In the Event BeginPlay, use an Add Point Light Component node. Right-click on the Return Value and
select Promote to Variable, so you just have to rename the variable to PointLight:

Of course, we could also have added the Point Light Component directly (remembering
to set the Light Mobility to Movable), but the point was to show how we can also
generate Lights at gameplay time.
3. Calculate the distance from the Player. This is easy, since we have Get Player Character which
retrieves the player (no cast is needed, since we don't need specific functions, but just retrieving the
location), and the Get Distance To node, which will calculate the distance for us:

343
Creating Dynamic Lighting in Blueprint

4. Create three variables of the float type so we can tweak them per our needs:
DistanceForActivation, DistanceBeginChangeColor, and DistanceEndChangeColor. We need to make
them all public by opening the eye next to their names (so we can change their values per instance based
in the Details panel), and assign default values if you wish. Of course, the values should be
DistanceForActivation greater or equal than DistanceBeginChangeColor greater or equal than
DistanceEndChangeColor (our future code will run under this assumption):

5. Create two other variables, this time of the LinearColor type, which will store the begin and the end
colors, BeginColor and EndColor:

344
Creating Dynamic Lighting in Blueprint

6. In the Event Tick, check the Distance from the Player with the variable distances, and implement the
logic. Check whether Distance from the Player is greater than DistanceForActivation. If so, we can use
the PointLight variable with the Set Visibility node (leave the New Visibility parameter unchecked):

The Tick function is very expensive and you should avoid its use, unless strictly
necessary. In this example, I used it for simplicity's sake, since we are learning how to
manage lights. In general, you should use timers for objects that don't need to be updated
every frame, and even an update every third of a second will work as well (the player will
345
Creating Dynamic Lighting in Blueprint
not notice the delay).
7. If False, we turn on the light by using another Set Visibility node (this time with New Visibility
checked). However, we don't finish here, we change the color of the light with the Set Light Color node.
In the New Light Color, we use a Lerp node (linear interpolation) with A and B respectively
BeginColor and EndColor. To determine the Alpha of the Lerp node, we take the distance from the
player and we subtract DistanceBeginChangeColor. From here, we obtain a positive value if the player
is further than DistanceBeginChangeColor, and we need to discard this case.
We can do it by using a min node between the result of the subtraction and zero. Take the value only if it
is negative. However, since it is negative, we want to convert it to positive, which we can do by using
an Abs node. Finally, we have a distance relative to DistanceEndChangeColor, so if we divide this
result with DistanceEndChangeColor, we obtain exactly the Alpha we were looking for (if the value is
greater than zero, it is not a problem):

346
Creating Dynamic Lighting in Blueprint
8. Compile and save the Blueprint.

And this concludes also the part on Dynamic Lighting. Don't forget to assign some values
to the variables and test it in the game!

347
Driving particle parameters from gameplay through Blueprint
Driving particle parameters from gameplay through
Blueprint
In our game, we're going to add some generic particle effects to add a bit more life to our
environment. Therefore, you will have a foundation to build and extend upon on as you
please. Since creating particle effects requires an entire chapter (or even a whole book)
of its own, this section will only focus on how to control an existing particle system using
Blueprints. If you have some of your own particle systems, feel free to use them,
otherwise, we will use some that are already made in this project files. You can find out
more about creating particle effects by visiting https://docs.unrealengine.com/en-
us/Resources/Showcases/Effects.
One thing to keep in mind is that previously Unreal was using a system called Cascade, so
if you have an asset pack, it might still be using this system. In fact, recently Niagara,
which is the new particle system, has been introduced and soon (if not yet has) will
replace Cascade. Just be aware of the difference in the moment for your own curiosity
open up a particle system (or even when searching for learning materials). However,
except for the type of variables, at Blueprint level it doesn't change much, the functions
are pretty much the same, and we will see them both.
When it comes to dynamically spawning a particle system, you have two choices: spawn
it on a specific location or spawn it attached to some component/actor. For Cascade
particle systems, you can use the following two functions:

348
Driving particle parameters from gameplay through Blueprint

For Niagara, instead, use these two:

349
Driving particle parameters from gameplay through Blueprint

From these four functions, you can get a reference to the Particle system, which you can
use to control it through blueprint. If you just drag it out and type Particle, you will
find many functions, but the most important ones, in terms of controlling behavior with
gameplay data, are those that let you set parameters within the particle system.
In the case of Cascade these are:

350
Driving particle parameters from gameplay through Blueprint

In the case of Niagara, these are:

351
Driving particle parameters from gameplay through Blueprint

I strongly suggest you to get a deeper understanding of particle systems by checking out
the official documentation and learning how to control those parameters by using
blueprints and the functions in the preceding screenshot. You can find more information
by visiting the following link: https://docs.unrealengine.com/en-us/Engine/Niagara

352
Expanding upon what you've learned here
Expanding upon what you've learned here
Here there are some exercises that allows you to test your skills and challenge your
abilities:
See whether you can create some other types of effects with the material. For example, can you change
the way that the material loads/fills?
Our Filling Material receives the FillingValue in Unreal Units. Try to transform the value into a
percentage directly in the Material Editor.
Try to modify the material so that the non-filled part has an outline (this might help the player in
understanding how much is left to collect).
Experiment with the lighting effects or light types. Can you make the light blink instead of changing
color?
The Dynamic light we created is cool, but it is just a decoration. Try to implement it on an Enemy, so
the player might see a light on the enemy when they get close. Or, you can have the light on the player,
and modify the code. Instead of calculating the distance from the player, it first calculates which one is
the closest enemy, and then it does the rest of the calculation with the distance from that enemy. In this
way, the player has a sixth sense for when the enemy is nearby!

353
Summary
Summary
We've reached the middle point of our second project in this book. Our games now look a
lot better than they did a few chapters ago. From AI to atmospheric improvements (lights
and particles), we've covered quite a lot of the technical aspects of making a game
experience more immersive. In this chapter, we covered the essentials of making our
game prettier. We looked at creating dynamic materials that can changed based on in-
game interaction. Then, we explored using Blueprints to affect particle effects. Finally,
we saw how we could manipulate lighting in UE4 using Blueprints.
In the next chapter, we're going to cover topics related to game analytics, how to use the
analytics Blueprint library and, more importantly, how to implement analytics in our
game. We will also cover blueprint debugging, functional testing, and level design. By the
end of the next chapter, you should have a level that not only looks good but plays well.

354
Game Analytics, Debugging, and Functional Testing
Game Analytics, Debugging, and Functional Testing
In this chapter, we are going to explore what game analytics is, why it is useful, and how
to implement it in our game within the use of Blueprint. Then, we will have a look at
some blueprint debugging tools, which might come in handy at any time. We will move
on to exploring functional testing, and gain an understanding of how it works and how we
can implement it for our game. Finally, we will finalize our project by giving some
examples of a map that has been built for this project, mainly to give you creative ideas
on how to implement them on your own.
With that said, let's get started with the following topics that will be covered in this
chapter:
Game analytics
Analytics blueprint library
Implementing analytics to our game
Blueprint debugging
Functional testing
Level design
Extending what you've learned

355
Game analytics
Game analytics
Collecting data from your game is very important, especially if you want to understand
your audience better, and to deliver better experiences in the future. This process of
collecting game data is called game analytics. You can imagine it as a way to store
specific variables at a certain time. For example, where the player is, how much money
she has, or how many health points she has after a boss battle. However, when you ship
your game, your players will be all around the world. Hence, you need a system that
collects this data over the internet. You can either create this system by yourself, set up
your own ad server (which is very hard to do if you're not an expert at this kind of stuff),
or use a provider (which offers an existing system for a fee, usually depending on your
volume of data). Therefore, if you have a small volume of data, some providers might
offer a free plan which you can experiment with; and eventually extend when the number
of your players increase, and thus, the volume of data as well.

356
Analytics Blueprint library
Analytics Blueprint library
Unreal has a very solid analytic system, which can work independently from the provider
you chose (or if you decided to create your own system). In fact, Unreal offers a way to
pack all the data you would like to collect onto a handy interface. Since this system
doesn’t have any dependency with the UClass (meaning it doesn't have dependency over
objects that the blueprint is able to manipulate), you will need a plugin that offers an
interface for blueprints. This is a built-in plugin in the engine, and you can activate it in
the following way:
Navigate to Settings | Plugins. In the Analytics section, you will find the Analytics Blueprint Library
plugin
Activate (as shown in the following screenshot)
Then, you will need to restart the engine:

357
Analytics Blueprint library
The picture shows the plugin already activated. If it is disabled, then at the bottom of the
Plugin window, Unreal will ask you if you want to restart the engine immediately.
It is important to note there are over 20 blueprint nodes that can be used to track data
within your game—ranging from basic events, all the way to player demographics—by
using this plugin alone. Hence, let's explore the range of information that can be collected
throughout the entire game experience—from a play session to the purchase of game
content. To do so, we need to understand which blueprint nodes we can use. The most
common blueprint nodes are as follows:
Start session node : When you are collecting information about a play session, make sure that each play
session is considered as an individual session. There are many reasons for this, for example, you can
determine how frequently and for how long a player plays your game.
End session node : This is when the analytics plugin (including those from a third-party source) will
stop recording events during the current session. Some providers will flush (remove) the data to their
data collector.
Record event node : is used to record an event that currently has no attributes associated with it. To
achieve this, we can use the record event node. An example of when to use this is if you want to count
how many times a user performs a specific option, such as access their inventory, or interact with
certain NPCs, and so on. It is important to also understand that recorded events can also contain a single
or multiple attribute, such as the following:
With a single attribute : This records an event with a single attribute by its name. By doing it like
this, you can compare the occurrence of a particular event among their individual attributes. For
example, imagine that players are collecting various resources, you can identify which resources
are the most popular (health, weapon ammo, and more).
With multiple attributes: This records an event that contains multiple attributes to provide context
for the event taking place. This is a perfect example of where you might analyze what players are
doing in order to improve the balance of a game. For example, are players upgrading certain
weapons (which may also be difficult to obtain) over other weapons to make them a lot more
powerful than other players?
Record item purchased node : This records the purchase (via an in-game currency) of an in-game item.
Therefore, it doesn't record "real-world" transactions (for example, downloadable content (DLC),
microtransactions, or more). Real-world transactions are tracked by the record currency purchase node.
Record currency given node : This records events during gameplay when a player obtains in-game
currency. For example, receiving in-game currency after defeating a boss, or trading an item. In this
way, it can give you insight about potentially problematic areas and to determine the efficiency of
players using in-game currency. Again, with this and with other areas, it can help you to balance the
game and distribute resources among players.
Record currency purchase node : This records purchases that are made by using in-game currency,
which are paid for by using real-world money. Such purchases include DLC or microtransactions. This
can be particularly helpful for games that are free-to-play, in order to identify what features of the game
bring the most revenue.

If you are using third-party user analytic plugins and you can't see them, double check
358
Analytics Blueprint library
that you have enabled the appropriate provider plugins in the editor.

359
Implementing analytics into our game
Implementing analytics into our game
Now that you have a good grasp of game analytics, let's implement a little example.
First of all, we need a provider to collect our data, otherwise, our system will not work.
Luckily, Unreal has a plugin that implements a local analytics provider for test purposes.
Therefore, instead of using an online provider, we will print our collected data into a
logging file.
Next, you will need to open the Plugins menu once again and, under the Analytics section
you will find the File Logging Analytics Provider plugin, as shown in the following
screenshot:

360
Implementing analytics into our game
Enable the plugin (and the Analytics Blueprint Library plugin if you haven’t already) and
close the engine. In fact, one more step is required, and we need to do this while the
engine is not running.
Open your project folder, and you will find a folder named Config. Inside this folder,
you will find a file named DefaultEngine.ini, which contains many settings for
your game. Open the file with any text editor and, at the very bottom, add these lines of
configuration, as follows:
[Analytics]
ProviderModuleName=FileLogging
SendInterval=5
Basically, here we are saying to use the FileLogging parameter (which we have just
activated) as our Analytic Provider, and a series of settings for that provider. In our case,
the parameter refers to how often all of the data should be flushed to the provider. In this
case, it is every 5 seconds (usually the value is higher, such as 60 seconds, but for
demonstration's sake, we will stick with 5 seconds). Save the file, and reopen your
project.
In case you would like to use more than one provider, you can do so by enabling the
Multicast Provider plugin (in the same way that you did with the other two plugins), and
in the configuration file, set this to be the default provider. Afterward, you can specify
any other provider you would like to use with the
ProviderModuleNames parameter, and separate them with a coma.
Now, we are ready to experiment with some analytics in our game!
We need to decide what we would like to have analytics from. For instance, we might
want to record every time a player picks up a collectible, and every time that a player
kills an AI. We want to record the timestamp of both of these events, so we will have a
Time attribute and insert the current playtime there.
Moreover, when the game starts, we start a new session, and every time that the player
dies, we close the session. As a result, you will have the play-through as different sessions
(this is just for demonstration purposes, you can also have a single session from when the
player starts the game until it ends, if you wish).

361
Starting the session
Starting the session
We should start our sessions as soon as the level loads. To keep things simple, we can use
the Level Blueprint screen (you can access this from the top bar of the
viewport: Blueprint | Open Level Blueprint). In particular, we can use the Begin Play
event to start recording our session. The only function to call is the Start Session
(Analytic | Start Session) without attributes (we don't want to add any particular attribute
to the start of this session), as shown in the following screenshot:

Thus, connect the Event BeginPlay node with the Start Session node and it should look
like the following:

362
Ending the session
Ending the session
The best point to end our session is still within the Level Blueprint screen. This time, we
will need the Event End Play option, as follows:
1. From the My Blueprint tab on the left, we need to click override and then select End Play, as shown in
the following screenshot:

363
Ending the session

As a result, the event will be created within a graph.

364
Ending the session
2. Now, before concluding our session, we would like to record the reason why this session ended. After
all, the End Play event carries this information with it. Thus, we can create a Record Event with
Attribute node (Analytic | Record Event with Attribute), as follows:

3. As you can see, this node has three string parameters. One is the Event Name paramater, in which we
can directly assign the End Session value. The second is the Attribute Name paramater, in which we
can name a End Play Reason value. Finally, the last one is the Attribute Value paramater, in which we
need to plug the End Play Reason value from the Event End Play value (this will automatically be
converted into a string). The graph should look like the following:

4. The last step is to conclude the session with the End Session node (Analytic > End Session). In the
following screenshot you can see the final code:

365
Ending the session

Now, we have learned how to create an event with an attribute. We will use the same
node over the next sections in order to implement analytics for when a player collects an
object, and when a player performs a kill or wins the game.

366
Recording an event when the player collects an item
Recording an event when the player collects an item
In order to record a collection by a player, we are going to use the same principle as
before: we are recording an event that the player has collected an object, and we use as
an attribute the at which time the player did it.
Let's open the BP_CollectableItem blueprint. At the end of Event Begin
Overlap session, just after the Destroy Actor node, we need to add our Record Event
with Attribute node with the name Item Collected, and the Time attribute. For the
value of the attribute, just use the Get Time Seconds node, as shown in the following
screenshot:

We used Get Time Seconds because it was easier, but if your game has some time
dilatation or performance issues that you want to track, you should probably keep track
of the time using another node, such as Get Real Time Seconds, which is not affected by
time dilation (in fact, when we save our analytics, we want to have real time).
As a result, we are now able to keep track of when a player collects an item.

367
Recording a kill, victory, and defeat
Recording a kill, victory, and defeat
Another thing that we would like to register for analytics purposes is when the player kills
an enemy.
Let's open the Third Person Character blueprint (or whichever blueprint contains your
enemy), and at the end of the Hit Projectile event, add the following self-
explanatory code, as follows:

As a result, we can keep track of when the player kills an enemy as well.
Let's now see how to record a victory. Recording a victory is very simple, and uses the
same logic of the events we have registered so far. Open the
BP_WinningTrigger blueprint, and at the end of the Won event, add the following code
(note that there is also a Quit node option to quit the game when the player wins the
game after a little delay, but the analytic part is just the Record Event with Attribute
node), as follows:

368
Recording a kill, victory, and defeat

For learning purposes, we are going to record a defeat using two parameters, instead of
only one. As a result, we are able to deal with an array of attributes for analytics.
In particular, we are going to record the time of when this event happens (there is nothing
new here as we'll use the Get Time Seconds node), and the player's position (we'll need
to get the player's pawn and get its location). However, passing more than one attribute to
a record node requires the use of arrays.
Let's start by opening First Person Game Mode, in which the player defeating event is
handled. Immediately after the Restart event, and before the Spawn Emitter event, we
need to add some code. In particular, we need to add the Record Event with
Attributes node, which allows us to not take just a single attribute as a parameter, but an
array of attributes. We can use the Make Array node to build our array, and decide how
many arrays there will be—in this case, too. Finally, we can make a single attribute with
the Make Attribute node.
This is the self-explanatory code, as shown in the following screenshot:

369
Recording a kill, victory, and defeat

Finally, our analytic system is complete. Now, it's time to gather the results!

370
Checking the results
Checking the results
Now, press play, and experiment a little bit in the test level you have created. After a few minutes, you
can stop and see what the results are. Since we have used the FileLogging provider, you can find all
your analytics inside the Analytics folder (which is within the Saved folder of your project). The
files are formatted in JSON (one of the most used file formats for data, since it is easy to read both by
machines and humans), and can be read by any text editor (so, open it with a text editor).
To give you an example of what to expect, these are the results of my play-through (this is a short one,
otherwise the results would be much longer), as follows:
{
"sessionId" : "713f65814c5a27b5d938ca98ce90b492-2018.11.10-17.21.11",
"userId" : "713f65814c5a27b5d938ca98ce90b492",
"events" : [
{
"eventName" : "Item Collected"
, "attributes" : [
{
"name" : "Time",
"value" : "4.762388"
}
]
}
,
{
"eventName" : "Item Collected"
, "attributes" : [
{
"name" : "Time",
"value" : "5.612642"
}
]
}
,
{
"eventName" : "Enemy Dies"
, "attributes" : [
{
"name" : "Time",
"value" : "7.813114"
}
]
}
,
371
Checking the results
{
"eventName" : "Item Collected"
, "attributes" : [
{
"name" : "Time",
"value" : "10.940619"
}
]
}
,
{
"eventName" : "Item Collected"
, "attributes" : [
{
"name" : "Time",
"value" : "20.673523"
}
]
}
,
{
"eventName" : "Enemy Dies"
, "attributes" : [
{
"name" : "Time",
"value" : "23.274094"
}
]
}
,
{
"eventName" : "Item Collected"
, "attributes" : [
{
"name" : "Time",
"value" : "30.445747"
}
]
}
,
{
"eventName" : "End Session"
, "attributes" : [
{
"name" : "End Play Reason",
372
Checking the results
"value" : "End Play in Editor"
}
]
}
]
}
In case I would have been killed by an enemy, the end of the log would look like the following (again
this is a short play-through):
{
"sessionId" : "713f65814c5a27b5d938ca98ce90b492-2018.11.10-17.20.58",
"userId" : "713f65814c5a27b5d938ca98ce90b492",
"events" : [
{
"eventName" : "Item Collected"
, "attributes" : [
{
"name" : "Time",
"value" : "4.549634"
}
]
}
,
{
"eventName" : "Player dies"
, "attributes" : [
{
"name" : "Time",
"value" : "9.939913"
}
,
{
"name" : "Player Position",
"value" : "X=606.313 Y=-400.577 Z=98.796"
}
]
}
,
{
"eventName" : "End Session"
, "attributes" : [
{
"name" : "End Play Reason",
"value" : "Level Transition"
}
373
Checking the results
]
}
]
}

374
Blueprint debugging
Blueprint debugging
Have you ever used, accessed, or done something that doesn't work the way that it is
supposed to? This is a common, albeit annoying process when it comes to game design.
Now, by this point, you should be quite well-acquainted with the use of blueprints.
Therefore, we're now going to look at the use of Blueprint for debugging tools. Debugging
is simply a process that focuses on checking your code (or blueprints), identifying issues,
and trying to find out where those issues are occurring and why. It often requires an
iterative approach in order to understand what the problem(s) are and how to resolve
them. More specifically, blueprint debugging is an extremely valuable and powerful
feature within UE4. The reason that it is am important feature is because it allows us to
perform many tasks. For example, it can allow us to pause the execution of a game in
Play In Editor or Simulate In Editor mode. From here, we can then navigate through any
graph of a Blueprint or Level Blueprint by using breakpoints (which we will discuss in
the next section).
Essentially, blueprint debugging allows us to step in, out of, and around or execution and
the ability to look at our call stack (the list of which functions called which function), so
that we can see the execution order and how we got to where we are in terms of blueprint
execution. While there is so much to say about debugging, this is outside the scope of this
book. However, this section will give you a small preview of what the blueprint
debugging systems can do and what the most common issues are when working with
blueprints.

375
Breakpoints
Breakpoints
Breakpoints are extremely useful when it comes to identifying issues within a blueprint,
by following the execution node by node to see what variables are set, what is going on,
and to see if something is not being set as it should be. In this way, you can isolate a node
(using the F9 key, or with the right-click menu) with a breakpoint, so that node will get
the focus, allowing us to step between each breakpoint of the blueprint.
You can see an example of a breakpoint in the following screenshot (in this case, it is
attached to the Start Analytic Session node, which we created earlier in this chapter), as
you can see from the red dot in the left upper corner of the node:

If a breakpoint is placed at an invalid location inside of the Blueprint editor, it may


appear yellow and feature an exclamation point. In some cases, compiling the Blueprint
will resolve the issue. If not, try holding the mouse cursor over the breakpoint icon to
reveal an explanation about why there is an error.
As a result, when you play the game, the execution will stop at this node, and you will be
able to check for variables and keep going a frame at the time. Isn't that awesome?

376
Debug tab
Debug tab
There are several different types of tools available for debugging blueprints. It is also
important to remember that different debugging controls will appear based on what type
of blueprint is being debugged. In addition, it will also depend on the current state of the
debugging session. These debugging tools include the following:
Watch window: This is designed to speed up the debugging process by giving you access to the
variables and nodes that you want to watch, even across multiple blueprints. This significantly helps to
isolate and focus on problematic areas.
Call stack: This is just a simple window that reveals the flow of execution between the Blueprint and
the native (C++) code, with the Blueprint function currently being executed at the top of the list or stack.
Execution trace: This stack provides a list of all the nodes executed in order from most recent.
Print to string: This is a very basic way to identify when an event occurs. It simply prints some text to
the console that only the developer will see. This is a good game developer practice. We have also
used this one before.

377
Some common Blueprint issues
Some common Blueprint issues
While debugging aims to resolve issues that are related to things not working as they
should, the following is a short list of some of the most common issues:
Naming consistency: Remember how we discussed the importance of naming conventions earlier in
this book? Well, this is because a misspelt variable, object, or even file name is likely to wreak chaos
later.
Collision/trigger: Are your triggers and collision meshes where they should be? Often, it happens that a
trigger/collision box is misplaced, or placed with a really large offset from the root of the blueprint.
Thus, if your character is not triggering something, check the collision/trigger box.
Duplicate objects: Sometimes an object that is supposed to disappear doesn't; it might happen if there
is a duplicate object and the first object actually disappears instead. So, make sure that is something that
is supposed to appear (or not) is the only instance of the object.
Wrong references: Just like bad naming can be a royal pain in the process, so too can referencing the
wrong thing. Make sure that the right object, file, variable, and so on, is being referenced (so, the
variables contain the objects that they are supposed to and not something else instead).
True and false: Is the right state to a file set/enabled/disabled? Perhaps they are in the inverse? It might
explain a lot.

378
Balancing the game
Balancing the game
A game needs to be balanced. It needs to have just the right amount of difficulty so that it
challenges players, but not so much that it has the player wanting to punch something (for
example, Dark Souls). Therefore, it is important to understand which parts of your game
need to be balanced. This is a vital process during debugging, because an incorrect
balance of the game can lead to several problems in your game, resulting in a very bad
game, even if the rest is well-designed. Be sure to test your game well and often from day
one, and try to keep it balanced.

379
Functional testing
Functional testing
There's nothing like a bit of good old functional testing to make sure that everything is
working as it should. Essentially, Functional Testing is designed to conduct gameplay
level testing and works by performing one or more automated tests. The tests that you are
most likely to run during your game's development will be functional tests. These will
probably be low-level or editor tests that need to be written for using the Automation
Framework system. You can find out more about the Automation System by visiting this
link to the official documentation: https://docs.unrealengine.com/en-
us/Programming/Automation/UserGuide.
In a functional test blueprint, you will have the following nodes to help you design the
test (along with a series of events that can be overridden):
Add rerun: This causes the test to be rerun for a specific named reason.
Finish test: This allows you to specify if the test has finished with a success or a failure.
Get current rerun reason: This returns the current re-run reason if we're in a named re-run.
Is enabled: This returns whether the functional test in the Target pin is enabled.
Is running: This returns if the functional test in the Target pin is currently running.
Log message: This logs a message for the functional test.
Run all functional tests: This triggers, in sequence, all the functional tests found on the level. The
Target pin is a Functional Testing Manager blueprint.
Set time limit: This sets a time limit within which the functional test needs to complete.

All the Target variables/pins on these nodes (except for the Run all functional
tests node) are referring to a functional test blueprint.

380
Functional testing within our game
Functional testing within our game
To show you an example of how functional testing works, we will create a simple
example where if the player falls off the ledge, there is a threshold for when they die. In
particular, the world kills the player pawn when a certain z value is reached. Of course,
this is a built-in feature, so it is almost impossible that this test would fail, yet it provides a
good foundation on exploring how functional testing works.
We can set up our functional test by doing the following:
1. Creating a new Level/Map.
2. Make sure that you include in the map's name the following prefix indicated in
bold, FTEST_yourFileName, otherwise, the automation tool will not pick it up! In my example, I
called the map FTEST_FallingOff.
3. Create a new Blueprint Class (under the All Classes section) called Functional Test.
4. We can call this Blueprint Class: BP_functionalTest_playerFalling. In this instance, you
can name the Blueprint whatever you want, there is no necessity to use a particular prefix like before.

5. Drag it (anywhere) into the scene, as shownin the following screenshot:

381
Functional testing within our game

Now, we need to set-up the conditions for the test; to do this, we first need to edit
382
Functional testing within our game
BP_functionalTest_playerFalling double-clicking on it.
The next step is to set the functional test within this blueprint. Let's start by defying when
this test is ready. In particular, we need the player pawn being valid in order to start the
test, as follows.
1. Under the Functions menu, select Overwrite , then Is Ready. This following screenshot should help
you:

383
Functional testing within our game

384
Functional testing within our game
2. Add the GetPlayer Pawn action (Game | GetPlayer Pawn).
3. Now, add a Valid function (Utilities | Is Valid).
4. Connect the Return Value pin into the Return Value node.
5. Enable the Return Value pin on the Return node.

This is how it should look like in the end:

Next, we need to determine if the player actually dies if they are outside of the playing
space. In order to do this, let's get back to the Event Graph and do the following:
1. Create a Get Player Pawn node (Games | Get Player Pawn).
2. Connect the Return Value pin to an Is Valid function node (Utilities | Is Valid).
3. Then, connect the Return Value pin from Get Player Pawn node into the Input Object pin of our Is
Valid node.
4. Connect the On Event Tick into the Is Valid node.
5. Drag from the Is Not Valid pin of the Is Valid node, and select Finish Test (Functional Testing |
Finish Test).
6. Lastly, to communicate to the testing that the player has died, we need to change the Test
Result function to Succeed.

As a result, at every tick (notice that the ticks begin only after the Is Ready function
returns true), we check whether the player pawn is still valid. In fact, the level will
destroy the player pawn once it has reached a certain z value (we are going to change this
value soon).
Thus, at the moment the player pawn is not valid (that is, they have fallen out of the
playing space), then the test succeeds. Once you have done all this, the graph should look
385
Functional testing within our game
like the following screenshot:

At this point, if the player pawn is still not destroyed, we need to know if the player pawn
has fallen over a certain z value. In fact, if the pawn is valid below this z, then it means
that the test has failed. To do this, we need to carry out the following:
1. Drag from the Return Value pin on the Get Player Pawn node, and select Get Actor Location
(Utilities | Transformation | Get Actor Location)

For improving the clarity of the Blueprint, you can create another Get Player Pawn node,
as is shown in the following completed graph.

386
Functional testing within our game
2. Then, drag the Return Value pin on the Get Actor Location node, and select Break Vector

Alternatively, you can right-click on the Return pin of the Get Actor Location node, and
select the Split Struct Pin, as shown in the following example:
3. Now, drag from the Z pin, and select Float | Float (Math | Float | Float | Float), so that we can see if the
player's position is below a certain Z- value
4. For now, set this value to -600

5. Drag from the Result pin, and connect it to the Condition pin of a Branch node
6. Drag from the True pin of the Branch node and connect it to a Finish Test node, this time we set the
Test Result pin as Failed
7. Finally, connect both the Finish Test nodes into a Quit node to automatically close the level

Once you have done this, you will have a node set up like the following screenshot:

387
Functional testing within our game

In the World Settings tab, you will need to make sure that the Kill Z value is changed to
something that is slightly different to the one that you have sent in the Float | Float node.
For example, if in the Float | Float node you set the Z-value to -600, set the Kill Z value
to -500. In this way, you can see if there is an issue with the threshold, and whether
players are dying when they hit that particular threshold or not. You can see an example
of these variables in the following screenshot (you need to open the World Settings tab
from the main interface of Unreal, so close the blueprint, and on the right, you will find
this tab):

388
Functional testing within our game

One last thing to do before we test what we have done is to actually let the Player Pawn
fall. In fact, there is the platform that you should either remove or disable collision. Once
you have done this, then your functional test is ready to be automated.

389
Session frontend for functional tests
Session frontend for functional tests
Now, it’s time to test our function test. To achieve this, let's do the following:
1. Open up the Session Frontend (Window | Developer Tools | Session Frontend).
2. Under the Automation tab, check to see if BP_functionalTest_playerFalling is listed. You might need to
expand the project category, and then expand the map (the map in which the test is present). You can see
an example of what you should be seeing on your screen in the following screenshot:

If for some reason you cannot see your test listed, try clicking on Refresh Tests.

3. Once BP_functionalTest_playerFalling is visible, you need to select it (tick the checkbox next to the
name) and click Start Tests. You will also notice that once the testing has occurred, it will (should) be
displayed as green, meaning that the testing was successful given the conditions that we had set, as
shown in the following screenshot:

390
Session frontend for functional tests

Congratulations! You have just run your (first) functional test. In the same way, you have
set this up, you can also test any part of the gameplay of your game. As a result, you can
test your new functionalities and test if they don't break the old ones.

391
Session frontends &#x2013; profiling tool
Session frontends – profiling tool
Performance is an ever-present topic in making real-time games, and it is an essential
thing to keep in mind while developing any kind of interactive experience. Since this
chapter is about debugging, and since we already have our Session Frontend window
open, it's right to point out that from here you can keep an eye on performance. Of
course, we are not going to face anything in detail, but just to point you in the right
direction when you will need a profiling tool.
To asses this in UE4, a Session Frontend or Profile tool allows developers to keep an
eye or understand where resources are being drained. UE4 covers many areas of
performance; and from the Session Frontend, you can open the Profiler tab, in which
you will be able to check the performance of your game during a session, as shown in the
following screenshot:

392
Session frontends &#x2013; profiling tool

We won't adventure further, but you can consult the official documentation here
393
Session frontends &#x2013; profiling tool
https://docs.unrealengine.com/en-us/Engine/Performance/Profiler if you are interested to
learn more about it.

394
Level design
Level design
So that we can put together everything that we've learned up until this point, let's put
together a basic level. In fact, the best way that we have to test out what we have done
for this second project is to build a level and finalize our project.
For our case, we'll create something along the lines of a maze where you will have
enemies spawn and chase you, all while you're having to collect spheres to complete the
purple statues like we did in Chapter 11, Making it Pretty. We are going to use the
Infinity Blade Grassland pack from the Marketplace, which is free.
When creating your level, try to draw a rough layout of the map on paper. Then, you
should create a place that is your reference point for the rest of the map. In my case, it
was the space just outside where the player spawns, as shown in the following screenshot:

395
Level design

Try to vary the design with a different environment, and try to keep it consistent with
your assets. You can see some examples of the level that we created for this project in
the following screenshots:

396
Level design

We can vary from a green cave...:

397
Level design

...to a purple corridor:

398
Level design

From a having some sight view on other parts of the map ...:

399
Level design

... to having a bridge on the water, ...:

400
Level design

... or even having the water to come up close to the border of the walkable area like here:
401
Level design

Of course, don't forget to place the final door, as shown in the following screenshot:

402
Level design

The following screenshot shows an overview of the map:

403
Level design

The same overview is shown in the following screenshot, but from the opposite angle:

404
Level design

Use your own fantasy to come up with something unique. You can download the project
files of this project, so that you can play around with the level and see how it has been
constructed. By reverse engineering, you can learn a bit more, but don't forget to practice
your own levels. Finally, share your work with others, and get feedback on it; I look
forward to seeing your work out there!

405
Extending&#xA0;what you've learned
Extending what you've learned
Now that we've covered quite a bit in terms of level design, why not try challenging
yourself to see what other things you can come up with, for example:
Are there other types of analytics that you want to collect within your own game? What are they? Ask
yourself why you need this information, and how it will be useful for improving the game?
What are some areas of your game that could be improved by using analytics? Do you want to find out
areas where players are encountering the most trouble (for example, dying)? Perhaps you want to see if
players are spending large amounts of time in one area over another?
When we did the analytics for our game, we only logged the timestamp. Try to think of other interesting
data that you would like to have at those moments. For instance, where the player or the enemy is/are
located, what is their distance, or how many bullets the player has used so far (you need to add a
counter in the blueprint for this).
What kind of functional test do you have in mind? Do you have a mechanic that you want to test
continuously in an automatic way? Try to write a functional test for it and see if this helps you out in
your workflow.

406
Summary
Summary
This is the last chapter for our second project. So far, we have covered quite a bit of the
fundamentals when it comes to game analytics and debugging with our blueprints. We’ve
covered what analytics is, the different types that are within UE4, and how they can be
used to improve our game. Then, we looked at debugging and how to use it to identify
and solve issues within our Blueprint(s). We then we looked at functional testing, session
frontends, and some general level design to tie it all together and finish up our second
project.
In Chapter 13, Level Streaming and World Composition, we will look at how to use level
streaming to optimize our games. In addition, we will also look at how to optimize the
player's experience while transitioning to different parts of the world. So, let's get moving
and transition ourselves into the next chapter!

407
Level Streaming and World Composition
Level Streaming and World Composition
Often, games are not made up of a single level. In many different types of adventures,
even online ones, there is the option to move between different worlds—or levels. When
we talk about levels here, we're referring to a map and not a player's level (for example,
status, progress, and so on.) Therefore, the level streaming feature makes it possible to
load and unload different map files (within your game) into memory, while allowing us to
toggle their visibility during play. In this way, we can choose whether other levels are
seen or not seen during play, and choose how and when to load them. Level streaming
makes it possible to have worlds broken up into smaller levels, so that only the relevant
parts of the world take up resources. As a result, if done properly, we can create very
large and seamless games, which can make the player feel as though they are playing
within levels that afford them endless possibilities in which to explore. The Elder Scrolls
series is a very good example of different level streaming techniques. While not done on
Unreal Engine, the game demonstrates a similar principle.
Of course, like many things in this book, there are several ways in which level
streaming can be done.
In this chapter, we'll cover the following topics:
How to use level streaming to optimize your games
How to optimize the player's experience while transitioning to different parts of the world
How to use World Composition to create large worlds

We won't go into detail, instead, we'll stick to a simple example to get you started on
level streaming and World Composition before jumping into the last project of this book,
in which we'll learn about multiplayer frameworks in UE4, and how to use them for
creating our own games.
We'll just scratch the surface of these two wonderful topics, but we cannot dedicate more
than a chapter to them. So, I hope this chapter will inspire you to learn more about these
topics.

408
Level streaming
Level streaming
When it comes to level streaming, you'll want to think about where the most appropriate
places are to do it. Especially if you don't want to have a break in the flow of the game—
in other words, not loading another level via a loading screen, but rather giving a fluid
experience to the player who believes she never left the level. The game, Portal (as
shown in the following screenshot), has a lift that takes you between the levels. While the
player is inside the lift, a new level is loaded. Of course, in UE4, you can create arbitrary
complex streaming systems, which allow levels to load in real-time, rather than
transitioning the player via a lift:

Screenshot from the game Portal by Valve Corporation


Ideally, you want to identify areas of your game that are perhaps resource-heavy (such
as, huge levels). For example, if you have levels that consist of both an interior and
exterior environment (such as, a forest and a castle), you may want to split up the
steaming between being in a forest and entering a castle, so that you can deliver an
optimal experience to the player (for example, without lag).
Obviously, we should try to unload the levels that are not used anymore before loading
another, to save resources while ensuring a smooth transition from one level to another.
409
Level streaming
As shown in the Portal example, this means that while a player is in the lift, the previous
level is unloaded before loading the next one. Both the operation to load or unload are
hidden to the player, who just has a fluid gameplay experience. In this section, we will
understand how loading and unloading levels work within UE4.
Of course, it is possible to load/unload levels using C++ as well. To know more about
how to do this, you can refer to the official documentation by visiting the following link:
https://docs.unrealengine.com/en-US/Engine/LevelStreaming/HowTo/StreamWithC.

410
Loading levels with Blueprints
Loading levels with Blueprints
Let's begin with learning how to stream a level using Blueprint. Once a player overlaps a
Box Collision component, we want to trigger the loading of another level. To begin, we
need to do the following:
1. Open the Content Browser tab and create a new Blueprint Class of type Actor.
2. Next, call the new Blueprint class, BP_LevelStream, and open it.
3. Now, we need to create a Box Collision component to trigger the level. Click on the Add
Component button in the Components tab, and select Box Collision.
4. You can rename the Box Collision component to LevelStreamBoxCollider, to make our blueprint
clearer.
5. If you want, you can to change the size of your Box Collision component (depending on where you will
place this Level Streamer). It is possible to do this within the Viewport window of the blueprint.
However, keep in mind that you can place multiple instances of this blueprint in the game and scale
each of them individually to better fit each level.
6. Now, in the My Blueprint panel, select the LevelStreamBoxCollider, and in the Details panel, under
Events, add OnComponentBeginOverlap. Once you have clicked the button, the event will be created
within the Event Graph tab.
7. Next, right-click to add a Get Player Character node.
8. Then, click and drag off the Other Actor pin from the OnComponentBeginOverlap event, then type
= into the context menu's search. Select the Equal (Object) entry to add the node. It is important to
remember here that you select the Equal (Object) entry and not another version, such as Equal
(Enum), as it won't work.

Remember that in the menu that opens when you right-click on the blueprint, there is
a Context Sensitive tick box in the top right. Having it checked makes it easy to avoid
such issues (at least, most of them) as the blueprint knows which functions are the most
relevant in a given case. However, this is not perfect, so if you cannot find what you need
you have to uncheck it to see all the options.
9. Now, connect the Other Actor pin from the OnComponentBeginOverlap event, and connect this to the
first pin of the Equal (Object) node.
10. Then, connect the Return Value pin from the Get Player Character node into the second pin of the Equal
(Object) node. You can see an example of this in the following screenshot:

411
Loading levels with Blueprints

11. Next, drag the red pin of the Equal (Object) node and select/create a Branch node.
12. Connect the execution output pin of the OnComponentBeginOverlap event node to the execution input
pin of the Branch node.

13. Then, drag the True pin from the Branch node and select/create the Load Stream Level node.
14. Right-click on the Level Name pin and promote it to a variable, then name the variable LevelStream and
make it Editable in the Details panel. As a result, we will be able to edit it for each instance of this
Blueprint. You can see an example of this in the following screenshot:

412
Loading levels with Blueprints

15. Finally, on the Load Stream Level node let's set to true both the toggles: Make Visible After Load and
Should Block on Load. As a result, once the level is loaded, it will immediately be shown to the player.
In the end, this is the final graph we have created:

At the Branch node, you could drag out from the Other Actor pin of the
OnComponentBeginOverlap event node and connect it to a Cast node instead. If the cast
succeeds, then continue with loading the level. Both ways are valid options to achieve the
same result. Using the Cast node is faster and ensures that the player has a specific
413
Loading levels with Blueprints
character; using the Equal (Object) node with the Get Player Character node uses more
nodes, but can accept any character that it is controlled by the player independent of
which one is it. Here is the graph with this alternative with the Cast node (assuming
the player is using a ThirdPersonCharacter node):

This concludes our blueprint to load a level. Of course, you will need to set the
LevelStream variable from the Details panel once it is placed within the level. To get a
better grasp of how this blueprint works, let's try an example.

414
An example &#x2013; streaming a castle
An example – streaming a castle
In this section, we are going to take the example of the castle from the beginning of this
chapter and put it into practice (with an extremely simplified version of a castle, just to
get to the core of our example).
To do this, let's create a new level and name it AWholeNewWorld. We can imagine this
level as the entrance of a castle (very stylized, just to show the example). In between the
doors, we can place our BP_LevelStream (be sure to scale this as needed). By the end,
you should have something similar to the following screenshot:

A quick mock-up of a level to demonstrate a likely place that you would put a level
streaming blueprint with an (albeit extremely simplified) entrance to the castle.

415
An example &#x2013; streaming a castle
The next step is to create another level, and name it Castle. In this level, we can place all
the interiors of the castle, so when the player enters within the castle, all of its interiors
are loaded. The following screenshot shows how the new level looks by itself (without
the first level, AWholeNewWorld, loaded):

As you can see, the level is without the lights because all of them are contained in the
AWholeNewWorld level. Of course, you can add any lights you might need for the
interiors of the castle.
A useful thing to know is that you can use the Levels menu (Windows | Levels) to drag
the newly created level inside the current one, so you can see how they look when both
levels are loaded (and decide which is the streaming method as well), as shown in the
following screenshot. As a result, this will make your life much easier when making levels
416
An example &#x2013; streaming a castle
that perfectly match once they have been loaded:

In addition, it's also useful to keep in mind that you will be able to decide which actor
goes into which level just by selecting the level.
More about the Levels panel will be discussed in the World Composition section of this
chapter.
The next step is to set the name of the level within the Level Stream variable of our
freshly created blueprint. Select it from the Viewport (and be sure to be in the first level,
in case you have both levels loaded), and in the Details panel, let's set the variable to
Castle, as shown in the following screenshot:

417
An example &#x2013; streaming a castle

Finally, we need to test our system. Once you walk into the Box Collision component,
you will load the Castle level on top of the current one, and the following screenshot
shows how it will appear (remember that it will not work until Castle is added in the
Levels tab):

418
An example &#x2013; streaming a castle

This concludes our example; next stop, unloading levels!

419
Unloading levels with blueprints
Unloading levels with blueprints
So, now that we have loaded a level, how do we unload one that is no longer needed?
Thankfully, it follows the exact same process as the previous section on loading levels.
There is a specific node in Blueprint that allows you to unload a level, and let you know
when the process is complete. To showcase this, let's continue using the
BP_LevelStream Blueprint, and add an additional functionality. In particular, we want to
stream out the level when the player leaves the Box Collision component.
Always from the Box Collision component, instead of On Component Begin Overlap,
let's create the On Component End Overlap event. From there, you can Get Player
Character and compare it with the Other Actor pin from the On
Component End Overlap event. After the Branch node, instead of Load Stream Level,
simply connect the Truth execution pin to a Unload Stream Level node. An example of
this can be seen in the following screenshot:

Like in the previous information box, you can use the cast version here as well. This is an
example:

420
Unloading levels with blueprints

As a result, we have a unique blueprint that it is able to stream in and stream out the same
level, and it showcases the basic functionalities of level streaming. Of course, it is then up
to you to implement your own system.
One last word about our example. We placed the BP_LevelStream blueprint at the
entrance of the Castle. However, as soon as the player goes through the entrance, the
Castle level is unloaded. To overcome this problem, you can either modify the blueprint
to one that suits your needs better, or directly extend the Box Collision component of the
BP_LevelStream blueprint to the whole space occupied by the Castle Level.
In this way, as far as the player is inside this box, the Castle level is loaded. The following
screenshot shows how the Box Collision component can contain all the staircases of our
simple castle:

421
World composition
World composition
Imagine that you have a large environment, kind of like the ones that you would find
within an RPG, such as Guild Wars 2. But more importantly, imagine working on that
level. This is easy enough if you're a team of one or maybe two, but not so much if you
have a large team that will need to work on the level simultaneously. Finally, imagine
handling such a big world all at once in the memory of your players' computers!
Therefore, the easiest way to understand World Composition is by describing what it can
do for your game; in fact, it is a wonderful tool that allows level designers to work in
team, as well as be able to manage loading and unloading from/to memory multiple
landscapes and massive levels. The idea behind World Composition is to simplify the
workflow for level streaming in case you have a huge world (consider it as an advanced
version of level streaming, which most of it is already taken care for, specifically
designed for large worlds). As a result, you can avoid using persistent levels to store
streaming information, since World Composition scans a specific folder, and treat all the
levels within it as streaming levels. In fact, this is possible because each level has some
information stored in the header that World Composition can read without loading the
level into memory.
Initially, all the levels are unloaded, with the exception of the persistent one. You are
always able to manually load and unload any part of this huge world, as well as with an
automatic distance-based level streaming.
Moreover, it is worth noticing that World Composition has a world origin-shifting feature
that allows you to create worlds not bound to the hard-coded value of WORLD_MAX
(which is a variable defining the maximum size of the world). So, if your world is bigger
than WORLD_MAX, then World Composition becomes your best friend, and the only
built-in solution available.

422
Activating World Composition
Activating World Composition
To active world composition, we just need to navigate within the World Settings window,
and select Enable World Composition, as shown in the following screenshot; it's as simple
as a click:

If you don't see the World Settings window, you can enable it by selecting (in the top
menu navigation bar) Window | World Settings, as shown in the following screenshot:

The window may prompt you to save your file. If this is the case, you just need to specify
where to save the level, since it has not been saved yet. Once you have done this, it will
make it a Persistent Level option, as shown in the following screenshot:

423
Understanding the levels tab
Understanding the levels tab
Within the Levels tab menu, you can create an empty level or add an existing level from
a file that you've already created, by selecting the Level drop-down menu, as shown in
the following screenshot:

Another useful thing to know is that when you select things within your scene (from the
Scene Overview window panel) you can create a new level. This is then automatically
added to the Levels window. Finally, within the Level panel menu, you have a few
options that you can toggle on/off as you please. These are described as follows in
reference to the following screenshot:

A brief description of each part of the Level menu is included in the following:
1. Level visibility: You can turn this on/off to hide the contents of a level
2. Lock: This allows you to prevent the level from being modified
3. Open Level Blueprint: This allows you to access the Level Blueprint
4. Save level: This allows you to save the current level

If the level is highlighted in blue, this indicates that it is loaded and is the current level.
Whereas, if it is white, it means that it is loaded by not current, and if it is grey, it is not
loaded. You can change the condition of these levels by right-clicking on them and
424
Understanding the levels tab
selecting from the menu to unload, load, make current, and so on.

425
Example of World Composition
Example of World Composition
As you have probably guessed, the best way to get a grasp of how World Composition
works is to create a small example. Let’s start by creating a new folder (for example,
WorldCompositionExample), and create a new level within it named BaseLevel.
It's important to note that if you create a level by right-clicking in the content browser,
the level created will be completely empty by default (no default platform). If one goes
through File | New Level, the menu with options opens.
Since World Composition works in big chunks (for example, squares of 20 km of side),
the default platform in our level is very small (about 10 m long). Thus, to use World
Composition, we need to have a large world (I remark again that you will need World
Composition only if you have a large world). Open the level, and let's extend the platform
to 20 km by increasing its scale to create a folder containing three levels, named
BaseLevel, AdditionalLevel1, and AdditionalLevel2, and open the BaseLevel. Your
Levels tab should look like the following screenshot (before enabling World
Composition):

Once we enable Word Composition, Unreal will ask us if we want to import all of the
other levels in the same folder, as shown in the following screenshot; of course, click on
OK:

426
Example of World Composition

This message shows up only if you have other levels in the folder, otherwise, World
Composition just gets enabled.
So, now the Levels tab should look like the following screenshot, and I have highlighted
what has automatically changed:

If you click on the World Composition button, next to the Levels drop-down menu (and
next to the Level Details button), you will have access to the World Composition tab, as
shown in the following screenshot:

427
Example of World Composition

If you double-click on your level (in the Levels tab), you will be able to load the level
within the World Composition tab, as shown in the following screenshot:

428
Example of World Composition

You can zoom out (for example, using the mouse wheel) as it won't look the same for you
at first.
If you also load another level, you will be able to easily move it with respect to the other
ones, as shown in the following screenshot:

429
Example of World Composition

This concludes our brief journey to World Composition. The following screenshot is
taken from the official documentation (https://docs.unrealengine.com/en-
US/Engine/LevelStreaming/WorldBrowser) so that you can have an example of how a
real World Composition looks like within Unreal. If you are eager to learn more, the link
of the official documentation is a very good place to start. Of course, we have just
scratched the surface, but the point of this chapter was to give you an idea of the
potentialities of these tools:

430
Example of World Composition

431
&#xA0;Origin rebasing
Origin rebasing
One last thing to be aware of before concluding this chapter, is Origin Rebasing, which
does exactly what the name suggests—it releases the origin, which, in this case, is the
origin of the level. There are many reasons why we should do this, starting with the fact
that smaller numbers have a higher precision within the engine. This means that
animations, physics, spawning, and everything that relies on coordinates, will run much
more smoothly when the coordinate is small. If you have a very large world, you want the
player to be able to explore the whole world without problems, thus when the player gets
too far from the old origin, rebasing it means to change where the origin is and make it
closer to the player, so that everything around the player (now closer to the origin) has
smaller coordinates.
At its current stage, Origin Rebasing is a feature of World Composition, and allows you
to create worlds that are virtually infinite and to go beyond the WORLD_MAX limit.

432
Summary
Summary
In this chapter, we have explored Level Streaming and World Composition. We have
seen how is it possible to trigger via a Blueprint of a Level Stream, and we made a simple
example to showcase this. Moreover, we have also seen how it is possible to do the
reverse and to Unload a Level, always via a Blueprint. Then, we have mentioned what
World Composition is, how to use it, and made a small example. I hope that this chapter
gave you some inspiration to learn more about these very interesting topics. Of course, I
suggest you start with the official documentation, which, after reading this chapter,
should be easy to follow and allow you to develop additional skills.
Next, in Chapter 14, Animating the Hound, we start our third and final project for this
book. More specifically, we will look at animation blueprints by learning how to animate
a hound. In addition, we will also explore the foundations of multiplayer games.

433
Section 3: A Sci-Fi Shooter
Section 3: A Sci-Fi Shooter
In this last section, the reader will learn how to make a shooter game that is playable over
a network with other players.
This section will include the following chapters:
Chapter 14, Animating the Hound
Chapter 15, Data-Driven Gameplay
Chapter 16, Foundations of Multiplayer
Chapter 17, Extending the Multiplayer Setup
Chapter 18, Adding Additional Features
Chapter 19, Building and Publishing

434
Animating the Hound
Animating the Hound
Welcome to Chapter 14, Animating the Hound! This is the first chapter of our last project
within this book.
In our third and final project, we are going to create a sci-fi shooter set in a dystopian
future during an invasion of genetically modified hounds, because why not? To kick off
our epic adventure, we will start by covering more complicated topics in Unreal. In fact,
we will explore the foundation of multiplayer games, go through many complex topics,
and ultimately create an experience that it is playable (like we did for the previous two
projects).
In this chapter, in particular, we will explore the following topics:
Animation Blueprints: A powerful asset that allows you to drive animations for our characters, along
with BlendSpaces, and Skeletal Meshes.

435
Setting up and planning our third project
Setting up and planning our third project
Before adventuring further, it's important to first get some planning done.

436
Project setup
Project setup
First of all, we need to create a new project. We can do this from the Unreal Launcher, as
we did for the past two projects.
For the purpose of this book, I'm going to simply call it Multiplayer Game. Of
course, I invite you to use your own fantasy and imagination to come up with a great
name!
As for the template, you can select the Third Person option under the Blueprint tab (as
we did for the first project in this book), but don't worry, because we will also be using
the first person character as well in due time. Finally, you need to decide if to include the
Starter Content or not. Unfortunately, we don't have enough chapters in this book to
repeat the level design process as we did for project 1 and 2, also because the focus of
this book is on Blueprints and not level design. Thus, for this project, you have the
freedom to come up with your own environment. In this chapter, we will go through how
to create the whole logic for our game, as well as some tips for when you create your
environment.
Coming back to our Creation screen, you should have something similar to the following
screenshot:

437
Project setup

438
The game
The game
A terrible kind of hound is invading us, and it is up to us to stop them. These hounds are
intelligent, they chase you, and attack you with their terrible claws. Will you and your
partner be able to defeat them? Look how scary are they in the following screenshot:

Basically, we are going to create a two-player co-op game. There will be an invasion of
very big hounds, and you will need to survive the waves without dying.
So, what do we need to do in order to bring this idea to life? Let's find out in these
chapters, we will start by animating our hound.
By the way, here is another sneak preview of our hound in the following screenshot:

439
The game

Okay, now we are motivated enough to start!

440
Importing and setting up the hound mesh
Importing and setting up the hound mesh
First of all, we need some kind of asset to represent our enemy/hound. Moreover, this
asset needs to be rigged (and properly skinned too), and with good animations. Such a
model is really hard to find, and usually, you need to pay a lot of money if you don't want
to build it from scratch.
Thankfully, on the Unreal Marketplace, you can find a pack that suits our needs, has
everything that we mentioned, and is free. I'm talking about the Quadruped Fantasy
Creatures by PROTOFACTOR INC, which you can find here:
https://www.unrealengine.com/marketplace/7f7775996f7442b187f6fa510ec9d289.

The pack contains four creatures, but we will use only the Barghest creature and some of
its animations. Once you have downloaded it and added it to your project, you can open
441
Importing and setting up the hound mesh
the QuadrupedCreature folder, and erase all the folders except the Barghest creature
(in this way, we don't have a file in our project that occupies space and that we don't
need. You can always add them at a later stage if you want to extend your game):

Keep in mind that it can take up to several seconds to gather together all of the
dependencies between all of the assets. Afterward, you will be prompted to confirm
deleting the assets, as shown in the following screenshot:

442
Importing and setting up the hound mesh

Just wait until Unreal unloads/deletes all of the assets and we will be ready to continue, as
shown in the following screenshot:

Now that we have all the assets, it's time to give a proper name to our enemy and keep
the name convention consistent. The files we have imported have Barghest as their
name, but instead, we are going to name our enemy Hound. As a result, all the blueprints
443
Importing and setting up the hound mesh
that we are going to create will be called Hound, and it will be useful to distinguish
between what we create and what we have imported.
Out of curiosity, Barghest is a mythological creature popular during the Middle Ages, and
is a "black dog with large claws". You can find more about it on Wikipedia
here: https://en.wikipedia.org/wiki/Barghest.
However, for the purposes of this book, we will stick with the name, "Hound", both to
distinguish between the content we create, and to keep the reading of this book simple.
The next step is to create a folder named Hound within the Content folder.
In the game we are creating in these chapters, the Hound will be the only enemy.
However, if you are planning to add more enemies, a cleaner solution would be to create
an Enemies folder within the Content folder and place the Hound folder within this last
one. As a result, your project will result in being much tidier and more organised.
Inside this folder, we need to create the following subfolders:
AI: This contains all the AI logic for our enemy in the game.
Animations: This contains all the animations and Animation Blueprints we are going to create (in this
chapter).
Sounds: This contains all the sound we are going to use.
Blueprint: This contains all the blueprints that are related to our hound.

When you have created the mesh yourself, you can have a folder named Mesh, which
will have all the materials and other assets that describe the character (for example, the
characters skeleton, and so on). Then, in the animation folder, you can directly place
all of the animations that you have for that character (that are now within the Barghest
folder).
Also, it is important to keep in mind that Unreal will not keep referencing an internally
empty folder. Therefore, either you put the assets inside the folder immediately, or you
create a specific folder when you need it.

444
1D_BlendSpace
1D_BlendSpace
In the context of animations, you might sometimes want to merge two or more animations
together. There are many ways to do this, such as some directly inside the Blueprint
Animation, some others in Blend Spaces, and others using slots. The easier blend space is
at one dimension (and that's why it's called 1D). It basically merges animations based on
a single variable. For instance, we need to blend between the idle animation and the
running one based on the speed of the character. This is exactly what we are about to
create.
Let's open the Animations folder within the Hound folder, in which we are going to
create our One Dimensional Blend Space. Right-click in the Content Browser, and in the
Animations menu, select 1D BlendSpace, as shown in the following screenshot:

445
1D_BlendSpace

Then, we need to choose a Skeleton on which this blend space will work, as shown in the
following screenshot:

A Skeleton is an asset that describes how the different bone of a Skeletal Mesh
(definition follows) are positioned (organized hierarchically) within the character. You
can imagine it as a (tree-)list of bones, which is used for knowing which animations are
compatible with which characters. More than one character can share the same Skeleton.
In fact, you have both the Mannequin Skeleton, which is a humanoid rig, and our
Hound Skeleton, which is a quadruped rig. Of course, even animations will have a
Skeleton associated to them, since they are information about how the different bones of
a Skeleton should move over time. In any case, for this book, you just need to know this,
446
1D_BlendSpace
but I suggest you to explore more on the official documentation.
A Skeleton Mesh is the actual Mesh of our character with a lot more information than
just a Static Mesh. In fact, it contains information regarding which is the Skeleton, which
are the weights (skinning) of the character to proper be animated, which are the Morph
Targets (and their weights), and much more. For this book, you just need to know that
the Skeletal Mesh is the actual character with all the information necessary to be
animated, and at every Skeleton Mesh, a specific Skeleton is associated.
Choose the Barghest Skeleton, and the 1D BlendSpace asset is created in your Content
Browser. Then, rename it Hound_IdleRun_1D, as demonstrated in the following
screenshot:

Double-click on it to open the BlendSpace Editor, as demonstrated in the following


screenshot:

447
1D_BlendSpace

As anticipated, this editor allows you to blend different animations based on a single
parameter (because the BlendSpace is 1D). So, in the middle of the screen, there is a
preview of what your animation will look like. At the bottom of the editor, you can find
the blend space itself, a line on which you will place different animations, and they will
448
1D_BlendSpace
blend according to where the parameter is set along that line. The green
diamond previews the value of such a parameter. On the bottom right, you can find all
the animations related to our Hound (along with Animation Slots, but we will not use
them).
On the right, there is the Details panel (which is useful to check the position of a
particular bone), and the Scene Preview panel (which allows you to modify how the
preview will look). On the left, there is the Skeleton Tree (in which you can see the
Skeleton structure), and the Asset Details panel for this Blend Space in particular.
Let's start by modifying the Axis Settings (the Horizontal one is the only one in this case)
within the Asset Details panel (it's located next to the Skeleton Tree tab, as you can easily
confuse it with the Details panel on the right) to better suit our needs. First of all, we
want to give a name to the parameter that will blend between our animations (so that our
project is tidy). In particular, we want to blend depending on the speed of the character,
so we'll call it the Speed parameter. Based on some trial and error, the value I came up
with (you are free to experiment and find values that suit your character) for
the Maximum Axis Value was 180, the rest can be at default. The following screenshot
shows how it should look now:

The next step is to bring the animations onto the BlendSpace. The first is when the speed
is at zero, which means that the animations pin needs to be at the extreme left. From the
animation menu, you can pick any of the three idle animations available. For this project,
I'm going with the BARGHEST_idleBreathe animation, as shown in the following
screenshot:
449
1D_BlendSpace

Then, drag and place at 90 (the value of the Speed parameter) the
BARGHEST_walk animation (not the RM one, which stands for root motion).
In this book, we will not face root motion, because we are going to use the non-root-
motion version of the same animations (because they are available). However, root
animation is very important in game development, and you can read more about it here:
https://docs.unrealengine.com/en-us/Engine/Animation/RootMotion.
Finally, place at the right end the BARGHEST_run animation (again, not the RM one).
450
1D_BlendSpace
Now, if you drag the green diamond from left to right, you will see the three animations
blending together. Isn't that cool?
This concludes our BlendSpace. Unfortunately, it's really hard (if not impossible) to show
motion on paper using only words; but if you are following along, you can definitely be
proud of what you've achieved so far. The following is a summary screenshot of the
BlendSpace timeline to help you out in case you are stuck (it has different green
diamonds at different points to show how the values and the animations should be; the
screenshot has been modified for your convenience, as in Unreal, you will only have one
green diamond):

Next stop, the Animation Blueprint!

451
Animation Blueprints
Animation Blueprints
In this section, we are going to explore how to create the Animation Blueprint for our
hound.

452
What is an Animation Blueprint?
What is an Animation Blueprint?
The first thing to understand about Animation Blueprints is that they are not the classical
blueprint we have been using so far. In fact, they cannot be placed within the game-
world, for the simple fact that they do not inherit from Actors. Therefore, they are a
different kind of asset. In fact, we will cover them only in this chapter, and if you wish to
continue exploring Animation Blueprint, you should probably watch some video tutorials,
or read a specific book about it.
However, Animation Blueprints come very handy in a number of situations. In fact, they
allow you to separate the animation logic from the rest of the logic that is tied to a
specific character. For example, suppose you are running a behavior tree, and set a
destination to chase after. We don't want to care about how the character should walk, be
idle, or attack. In fact, when we program the behavior tree, we just want to think about
the AI logic. On the other hand, when we work on the Animation Blueprint, we don't
want to think about AI.
As a result, the Animation Blueprint just has some variables, and knows where to take
their values, but it doesn't care about how those variables are set. For example, if there is
a Boolean variable determining whether to attack or not, we don’t care when the
character needs to attack based on certain conditions; but we know that if that variable is
true we need to play an attack animation.

453
Creating the Animation Blueprint
Creating the Animation Blueprint
As always, in the Animation folder of our hound, we are going to create an Animation
Blueprint. The procedure is really similar to how we created the BlendSpace: right-click
in the Content Browser menu, select Animations, and then Animation
Blueprint (Animations | Animation Blueprint), as shown in the following screenshot:

454
Creating the Animation Blueprint

455
Creating the Animation Blueprint
Then, Unreal will ask you which is the parent of this Animation Blueprint, and on which
Skeleton it should work on. Don't choose any parent, since we are going to create
everything from scratch, and as for the Skeleton, we select the BARGHEST one, as
shown in the following screenshot:

Afterward, let's rename the asset we have just created to Hound_AnimBP, as shown in
the following screenshot:

456
Creating the Animation Blueprint

Double-click on it to open the Animation Blueprint Editor, and you should see something
similar to the following screenshot:

457
Creating the Animation Blueprint

An Animation Blueprint is made mainly of two graphs, the Event Graph, which is very
similar to the Actor blueprints we have been using this far, and the Animation Graph, in
which we need to build an Animation State Machine. You can have access to these two
options from the bottom left menu (My Blueprint panel). The Event Graph is
458
Creating the Animation Blueprint
responsible to communicate with the rest of the world (for example, the Character
Blueprint) and set variables; whereas the Animation Graph should only care about what
happens to the local variables (set by the Event Graph).

459
Event Graph
Event Graph
By default, once you open a newly created Animation Blueprint for the first time, the
view is set on the Event Graph.
Let's start in order, and think about what kind of information this Animation Blueprint
should have. For sure we need the current velocity of the character (in this case the
hound), since it will be used to blend between the idle and run states. Then, we need to
know whether the hound should currently attack, or whether it has been shot to death.
Therefore, let's create three variables from the My Blueprint Panel in the bottom left:
Speed (of the float type), bShouldAttack (of the Boolean type) and bIsDead (of the
Boolean type ), as shown in the following screenshot:

The next step is to assign at each frame, the values of these three variables, and we can
do this in the Event Graph of the Animation Blueprint. If you are not already in the
Event Graph, just double-click on Event Graph in the My Blueprint panel (refer to the
preceding screenshot). There are two nodes already in the graph because it is very likely
that you are going to use them (and we actually will).
460
Event Graph
These are Event Blueprint Update Animation, which is the event that updates the
current state of the animation, and we will use it for assigning the variables, and Try Get
Pawn Owner, which returns the pawn animated by this Animation Blueprint, as shown in
the following screenshot:

Drag from the Try Get Pawn Owner and create a ? Is Valid node. Connect the pin from
the event into this new node. We do this step to ensure that the reference given by Try
Get Pawn Owner is valid, otherwise, it's pointless trying to access the information within
it. So far, this is our graph:

461
Event Graph

Always drag a Get Velocity node from Try Get Pawn Owner. This returns the current
velocity of the animated pawn as a vector. However, we only need the length of this
vector, so we can create a Vector Length node to get just that from the vector. Finally,
from the? Is Valid pin, drag and SET the Speed variable to the Length of the velocity
vector, as shown in the following screenshot:

462
Event Graph

The last step would be to assign the two Boolean variables. However, we will come back
to this at a later stage, since we will need to have access to the specific blueprint of the
hound (which we still need to create). So, as a reminder, we place the two SET functions,
as shown in the following screenshot, but we will assume for now that the Animation
Blueprint has the right values for all and three the variables. Just keep in mind that we
need to finish this graph:

463
Event Graph
We will finish this event graph in the next two chapters, when we actually create the
blueprint for our hound. The next step is to properly set up the Animation Machine.

464
Animation Graph
Animation Graph
Now it's time to pass at building the Animation State Machine, which is possible within
Animation Graph. From the My Blueprint panel, double-click on Anim Graph, and you
should see something like this:

465
Animation Graph

This is a particular kind of graph in which the main information that connects through the
nodes is animation data. In the current stage, we are going to use just the basic features.
In particular, we will just use a single-state machine, which is where another graph tells
our hound which animation should play based on the current values of the variables, as
466
Animation Graph
well as which animations are currently playing. In order to create a new state machine,
right-click anywhere, and select State Machines | Add New State Machine…, as shown
in the following screenshot:

We can rename the State Machine as we choose (if you select it, you can change its
properties, including the name, in the Details panel on the right). For instance, we can
rename it as Hound Main State Machine. We need to connect the output of this State
Machine to the Input pin of our Final Animation Pose node. This means that all our
animation will be driven exclusively by this State Machine. Your graph should look like
467
Animation Graph
the following:

If you double-click on the State Machine, you can access its graph. At the moment, we
have only one node called Entry. Right-click anywhere, and create a new state. We can
rename it as Idle/Run, and connect the Entry node to it. As a result, as soon as the State
Machine runs, it will start by showing this Idle/Run state:

However, at the moment, this Idle/Run state is empty. So double-click on it to open


another nested graph.
The Animation Blueprints are plenty of many nested graphs, so be sure to check the bar
on the top to see in which part of this nest of graphs you are. You can also use this bar to
navigate and click on just one of the nested graphs, and the editor will focus on that part.
The sooner you get comfortable to the idea of nested graphs, the better you will be able
to handle and manage Animation Blueprints.
In this sub-graph, we can drag from the Asset Browser panel in the right bottom corner of
the Blendspace we created earlier. Once it is in the graph, we can drag our Speed
468
Animation Graph
variable (from the My Blueprint panel, in the bottom left corner) into the graph and feed
it as input to our BlendSpace. Finally, connect the result of the BlendSpace to the Output
Animation Pose of this state, as shown in the following screenshot:

Next, we need to go back to the State Machine and add a new state; this time we can call
it Attack. Then, connect the Idle/Run state to the Attack state by dragging from the first
onto the second. The trick is to drag from the lighter shade border. If you try to drag from
the middle, the state will simply move on the graph, as demonstrated in the following
screenshot:

469
Animation Graph

Once again, we need to fill the Attack state with some animation. So, double-click on it to
have access to its sub-graph. Here, we can drag the
BARGHEST_jumpBiteAggressive animation from the Asset Browser panel, and
connect it to the output:

Coming back to our State Machine, we have a connection between the Idle/Run state
and the Attack state. However, we need to define a rule that triggers this transition.
I'd like to point out that there's a Compiler Results tab on the bottom. If you compile and
save the AnimBP at this point, you will see a warning that Idle/Run to Attack will never
be taken. Which is exactly what we're about to fix. It's a good habit to keep an eye on the
compiler results.
You can think of a transition rule like a condition, so that when it is met (it is true), then
the transitions between the two states happen. If you hover your mouse on the transition,
you can see a preview of the rule. In our case, we haven't defined anything yet, so it will
be empty, as shown in the following screenshot:

470
Animation Graph

If you double-click on the symbol of the transitions, you can have access to the sub-graph
of the transitions to define a condition. In this case, the conditions are very simple,
because we can just drag our bShouldAttack variable into the graph, and connect it to
the output. As a result, this transition will take place when the bShouldAttack variable
has a value set to true, as demonstrated in the following screenshot:

Next, we need to add a new transition in the State Machine, which can bring us back
from the Attack state and to the Idle/Run state. In fact, our hound might stop attacking
to go back to idling or running, as demonstrated in the following screenshot:

471
Animation Graph

Now, open the transition graph, and this time the condition to meet is the opposite: the
bShouldAttack variable needs to be false for the transition in order to take place. So, we
can just invert its value with a Not node, and plug it into the Result node, as follows:

Finally, we need an addition state in our State Machine for when our hound dies. So let's
create another state and called it Dead. From both the Attack and the Idle/Run states,
create a transition towards the Dead state. However, do not create the transition back; in
fact, our hound cannot go back to run or attack once dead. So, from the perspective of
the Animation Blueprint, we reach this state, and that's it. It will be the logic in our hound
blueprint to do the rest (for example, destroying the hound actor after a while). So, the
following screenshot is what our State Machine looks like so far (we have finished this to
add states and transitions):

472
Animation Graph

However, we still need to finish to define the Dead state and the two transitions. Double-
click on one of the two transitions, and use the bIsDead variable to trigger the transitions.
Repeat the process for the other transition as well (their sub-graphs should be identical).
The following screenshot demonstrates how both of them will look:

Double-click on the Dead State and let's add the


BARGHEST_deathAggressive animation, and plug it to Output Animation Pose, as
shown in the following screenshot:

473
Animation Graph

It's important to understand that, by default, all of these animations loop. In the case of
the Death animation, we don't want it to loop over and over again, rather we would like it
to play once, and that's it—it stays like it is in the last frame of that animation. Therefore,
we need to select the BARGHEST_deathAggressive animation and, in the Details panel
on the right, there are a series of options to choose from.
In front of each option, there is a (As pin) checkbox, because you could even expose
each one of them as a pin in the graph, in case they depend from something else. In our
case, we don't need this, but keep it in mind when you build your own Animation
Blueprints.
We need to uncheck the Loop option, as shown in the following screenshot:

474
Animation Graph
This concludes the creation of our Animation Blueprint. You can compile it (to check if
we did everything correctly), and save the asset.

475
Extending what you've learned here
Extending what you've learned here
In this chapter, we have learned a lot about animations, BlendSpaces, and even
Skeletons and Skeletal Meshes. So, here there are some exercises to extend what you've
learned in this chapter. In particular, you can either extend the hound animation sets, or
implement another character. Keep in mind that in both cases, you will need to focus
more on the next chapters. We suggest that you first finish project 3, then come back to
this section for each chapter, and extend upon what you have learned to enrich your
game even more. Here are some suggestions of what you can try next:
Create other enemies: The free pack from the Unreal Marketplace comes with four assets. We have
been using one of these, and the other three we have erased. Open a new project, and re-import the
Quadruped pack. Then, select one of the folders containing the creature you want to animate (do this one
at the time, so you can focus on creating one character at a time). Right-click on the folder, and under
Asset Actions, you can migrate these assets in the Multiplayer Game Project. Now that you have the
assets you want, you can focus on using one of the creatures to create another enemy! They are fully
rigged and have plenty of animations. Take your time in exploring the various animations available,
create a BlendSpace for idling/walking/running; ultimately recreating what we have done with the
hound, but with another character.
Extend the hound: If you navigate through the animations of the hound, there are plenty that would be
interesting enough to implement within our Animation Blueprint (and in all the assets that control the
hound's behavior). Try exploring them, and choose how to extend the behavior of your hound. For
instance, there is a "hit" animation. This would be nice to play when the hound is hit (maybe on the
head?). Of course, any modification will require some extra effort in the next chapters as well to
implement these new features, but the result of learning is worth the effort!
Customize the hound, or create different versions of it: If you have a look at the Barghest folder,
you can find that there are more customizations available. In fact, there is an optional tail and mane
which you can use to give a different look to your hound. Moreover, you can create different variations
of the same enemy to vary the gameplay. Or even give different stats (such as, damage and health) to
each one of them. Most of the work for this will be in the other chapters, but here, you can check how
the Mane and the Tail are Skeletal Meshes too, and how they should be animated. The answer is simple,
but I will leave it up to you to explore the assets.

476
Summary
Summary
In this chapter, we have set the course for the remaining part of this book. In fact, we will
be creating a survival co-op multiplayer game. In particular, we have explored how to
import a character within our project and configure it to properly use in our game. Then,
we have explored BlendSpaces as a way to blend between different animations based on
a set of parameters (in our case only one, the Speed of the hound). Finally, we explored a
lot with the Animation Blueprint for our hound, so that in the next chapters we can focus
on the logic, and the hound will be automatically animated. This was a lot of stuff to
digest, so take your time, or take a break.
Next, in Chapter 15, Data Driven Gameplay, we are going to look at things such as,
Structs, DataTables, and Construction Scripts. In particular, what they are and how to use
them within Unreal to create interesting gameplay.

477
Data-Driven Gameplay
Data-Driven Gameplay
It appears as though you have survived the hounds and made it to Chapter 15, Data-
Driven Gameplay. It's good to have you here!
In this chapter, we're going to look at things like Structs, DataTables, Construction
Scripts, and how to use it all together to create some interesting gameplay. These will
help us significantly at a later stage because they will allow us to create more organized
Blueprints. This makes life easier when it comes to tweaking parts of our game down the
developmental pipeline. More specifically, this chapter will cover the following:
What are and how can we use Structs with Blueprints
Using DataTables with Blueprints, especially for our Enemy Hound
Using Construction Scripts to build our Hound

So, let's dive in!

478
What a Struct?
What a Struct?
Interestingly enough, we've already used Struct types many times. A Struct is a collection
of different types of data that are all combined together into a single variable. The easier
way to think about this is to think of one that we have used previously in our projects—
the Vector Struct. The Vector Struct contains three pieces of information, which
comprise the X, Y, and Z float. These are all related to each other as they define a
location within the game space. In addition, a Struct can also contain subproperties or be
nested. The most simplistic explanation of this is to think of the Transform Struct, which
contains Location (a Vector Struct), Rotation (a Rotator Struct), and Scale data
(a Vector Struct) about an actor all within a single element. Therefore, it contains many
different (nested) Structs to make up a larger overall Transform Struct.
You can break a Struct to see the elements that make up a Struct. We will cover breaking
Structs later in this chapter.

479
Using Structs with our project
Using Structs with our project
So when would we want to use a Struct within our game? The answer to this is simple—
when you want your game to be organized! When you have detailed games, characters
alone can consist of many different variables (name, health, class, lives, and so on). So,
in this case, a Struct is a way to organize all these different variables into a nice structure.
Also, the other advantage is that you can reuse the same structure in different contexts.
There have been many cases where developers have created Structs but have found out
down the road that they need to be modified. Therefore, it is important to remember that
when you need to or are changing Struct breaks, it will affect all Blueprints that use it.
So, by planning your Structs carefully, you can avoid frustrating issues later on!
In particular, in our project, we are going to use a Struct to keep bits of information
together, and ultimately build data-driven gameplay. In fact, we are going to build a
Struct for the main stats of our Hound.
When we think about which kind of stats that our Hound should have (or better, which
kind of stats we should be able to modify easily), there are four that we are going to use
in this multiplayer project:
Max Health: the maximum health held by the enemy character
Speed: the speed at which the enemy moves
Bite Distance : the distance at which the enemy should start biting the player
Health Recovery Rate : the rate at which the enemy recovers health

Now that we have established what kind of struct we need, let's create one!
Of course, we can create a similar Struct for the Player Character, but this is left as an
exercise.

480
Creating Structs
Creating Structs
As we have previously discussed, we've already created or used some Structs such as the
Transform or Vector Struct, but let's look at a more complicated example. Now, since our
sci-fi game is set in a dystopian world infested by big and terrible Hounds, the kind of
gameplay that we might have will be fighting with different monsters (or different types
of Hound). Therefore, we could create a Struct that would help to keep track of the stats
of each type of monster (for example, class, health, lives) that the player will encounter.
In our case, we want to track the stats we mentioned in the previous section. Therefore,
let's create a new folder in our Project, for instance, GameplayData (and, if you want, a
subfolder named Structs). Within this folder, right-click and select Blueprints | Structure
as shown in the following screenshot:

481
Creating Structs

Once created, let's rename it EnemyStatsStruct. If you double-click the asset, you can
open the Struct Editor (at the moment our Struct contains just a default variable):

482
Creating Structs

Here you are able to create your structure, determine how many variables, which types,
and their default values. Let's start by modifying the MemberVar_0, which is the only
variable in our Struct at the moment. We can rename it as MaxHealth and set its variable
type to Float:

483
Creating Structs

It is always useful to spend a few seconds more to fill up the additional information which
might be useful to other team members properly. Structs allow you to set a tooltip for
each variable. This can be very handy when your project grows in size. You can either
specify the tooltip when you create a new variable (the little box below the Add New
Variable button) or modify the tooltip for each variable by clicking on the arrow next to
their names (as shown in the preceding screenshot). For instance, you can use as a tooltip
the descriptions we gave to the different variables earlier in the chapter. Moreover, in this
little menu, you can also specify if the variable is editable or not.
Next, we can click on the New Variable button. It should already have the type Float
selected (otherwise we make it of type Float; in fact, all the variables in this Struct are of
type Float). You can click the button multiple times to add more variables. In the end,
you should have four variables, respectively named MaxHealth, Speed,
BiteDistance, and HealthRecoveryRate, as shown in the following screenshot:

484
Creating Structs

The next step is to decide some Default Values for these variables. Even though it is
really hard to think about what would be the right values at the current stage, it is always
better to approximate the right value, rather than leaving it as zero (which avoids much
debugging time later on). You can always change them subsequently, in case you need to.
In this example, I'm going to give the default values:
MaxHealth: 100
Speed: 250
BiteDistance: 320
HealthRecoveryRate: 0 (we don't want the enemy to restore any health by default)

485
Creating Structs
Once we have assigned these values, this is what our EnemyStatsStruct should look like:

We can finally Save the Struct and close the Editor. Our EnemyStatsStruct is ready to be
used!

486
Accessing Struct information
Accessing Struct information
Once you have created a Struct, you will more than likely want to access its information
at some point while you're creating Blueprints for various reasons. Within the Unreal
Context, accessing Struct information is called Breaking Structs (Breaking Structs
sounds horrible but it's actually something that you will get used to), whereas the process
for creating a new structure is called Making Structs. Then, once we have a Struct in our
project, in our case EnemyStatsStruct, Unreal automatically creates three nodes for use.
You can see them if you right-click on any Blueprint:

Let's see them in a bit more detail:


Break EnemyStatsStruct is a node that allows us to access the information within a Struct of type
EnemyStatsStruct:

Make EnemyStatsStruct is a node that allows us to create a Struct of type EnemyStatsStruct:

487
Accessing Struct information

Set members in EnemyStatsStruct is a setter node that allows you to change some values within the
structure without breaking one and recreating it:

It is a very useful, but not very well-known node. Once you have placed it, you can select
it and, in the Details panel, choose which pin to expose that needs to be changed, as
shown in the following screenshot (for example, let's change the Speed):

So then, the node changes to expose the pin(s) we want to change:

488
Accessing Struct information

Moreover, if you want to access particular information within a Struct without using a
Break [NameStruct] node, you can actually Split the pins if you just want to pull
something out to use. To do this, simply right-click on the Split Struct Pin (on any node
that contains it, both as input or as output) and select Split Struct Pin, as shown in the
following screenshot:

So, if we do it with this Generic Node on its Output Pin of type EnemyStatsStruct, we
obtain something like this:

489
Accessing Struct information

This concludes our discussion on Structures. So if you ever need them, you know how to
use them.
For this project we are going to use the EnemyStatsStruct within a Data Table, so let's
move on to the next section!

490
Using DataTables
Using DataTables
Let’s begin by addressing what a DataTable is. Simply speaking, it is basically a table of
data, like a spreadsheet within UE4. DataTables can be created inside of UE4 or they can
be brought in from an external source such as an Excel spreadsheet. The useful part of
importing a DataTable is that you can modify the original file (given you keep it at the
same location), and then you can reimport it within the same table, updating all the
blueprints that reference that DataTable. As a result, you will be able to change the
values of your stats (for objects, enemies, and so on) just in one spreadsheet. This is very
powerful!
When would you use a DataTable? You can use DataTables in a variety of situations. In
general, you use one when you have a collection of data with similar properties used
across your game, and you want to be able to control them easily, without chasing every
single Blueprint to change just a value to play-test whether your game is more balanced.
Also, it is important to understand that data tables are not databases. In fact, once a value
is set, you cannot change it at runtime.
There are some data structures that work as a database in Unreal. Actually, they can even
be persistent among sessions, but we are not going to cover them here, because mainly
they are held in C++.

491
Creating a DataTable
Creating a DataTable
A Data Table is an asset within the context of Unreal. Thus, it can be created from the
Content Browser, as with many assets.
Navigate to the GameplayData folder that we created earlier and right-click to open the
menu. Select Miscellaneous | DataTable, as shown in the following screenshot:

492
Creating a DataTable

Unreal will now prompt you to Pick a Row Structure, just as in the following screenshot:

What does it mean to Pick a Row Structure? Well, any spreadsheet that contains data has
a series of columns that determine how each row is structured. Imagine a table of
workers. You will probably have a column for the Name, another one for Age, and a final
one for the Assigned Department. This means that these three values (Name, Age, and
Assigned Department) need to be in each row that identifies a single worker. Thus,
picking a row structure means to specify to Unreal what all these different columns are
(and so how each row is structured).
To specify this structure, Unreal uses Structs (and that's why we focused our attention on
these earlier in the chapter). In particular, Unreal wants an already created Struct to be
assigned. Thankfully, we already have one, which we have made previously called
EnemyStatsStruct. Therefore, from the drop-down menu you can select it, as shown in
the following screenshot:

493
Creating a DataTable

Then, you can press OK, and Unreal will create the DataTable asset for us. You can
rename it Enemies Table. In fact, there will be a table containing stats for each enemy:

494
Modifying values within the engine
Modifying values within the engine
As anticipated earlier, we can change the values within the engine if we wish, with a
special built-in editor. Whether to do/use it or not depends on what will be the final use
for the Table. If you already have an external table, it is better that you modify that one
instead and reimport it. However, for small tables (like in our case), or for prototyping (or
very small) changes, you can use Unreal's Table Editor.
Another advantage of using the built-in editor is that it is much easier assigning types that
are different from the usual string, float, and so on, such as a Texture2D. This is
something to keep in mind when you build your table.
However, in our case, we have only floats, but we will still use the editor for simplicity's
sake. So double-click on our EnemiesTable to open its editor, as shown in the following
screenshot:

At the moment the table is empty, but at the top, you will notice that our Struct is used to
generate the different column types. Moreover, there is an extra column at the beginning.
This is because each row needs to have a unique identifier; you can consider it as the row
name. This is very important because this key allows us to retrieve a specific row at
runtime.
Let's start by creating a new row by pressing the + button in the Row Editor tab at the
bottom part of the editor. This is what our screen should display after we have pressed
495
Modifying values within the engine
the button:

Please notice that all the default values for our columns are retrieved from our Struct and
placed in the row. The default name of the row is NewRow, so let's change it into
something more useful for us. Since these are going to be different enemies, we can
rename each row as a type, such as TypeA, TypeB, TypeC, and so on. You can change
the Row Name from the Row Editor on the right (the drop-down menu on the left allows
you to select the row you want to edit; you need to edit one row at the time). Once you
have renamed the row as TypeA, it should look like the following screenshot:

496
Modifying values within the engine

With our default values, we have our TypeA enemy ready (you can change these values
if you need to). So, let's create a TypeB enemy, a more powerful one, maybe like a boss.
Once we have added a new row, change the values so the MaxHealth is now 180, the
Speed is 265, the BiteDistance is 350, and the HealthRecoveryRate is 0.25, and this
should make a pretty tough boss-like enemy for our players. This is what it should look
like:

497
Modifying values within the engine

Save the DataTable (EnemiesTable), and close the Editor, because we are now ready to
see how to use a DataTable in Blueprint.

498
Retrieving DataTable values
Retrieving DataTable values
Unreal has specific nodes to handle or read DataTables at runtime. If you right-click on a
Blueprint Graph, there is a section named Data Table, which seems promising, and under
it, there are four nodes for handling data from DataTables:

Once again, notice that there are no setters, because DataTables are not supposed to
change at runtime, but rather be a collection of data that can be easily updated during
development, but then be static once the game is running.
However, the best and most used node is not listed here. Instead, it is hidden under the
Utilities category and it is named Get Data Table Row, as shown in the following
screenshot:

499
Retrieving DataTable values

Get Data Table Row: This is the most useful node, since it retrieves the data structure associated to a
specific row (and has execution pins for whether the row is found or not). This is how it looks:

Once you select a specific DataTable, in our case EnemiesTable, a useful drop-down
menu next to the Row Name pin appears to fast-select a Row Name (you are still free and
encouraged to use the pin to set the Row) as shown in the following screenshot:

It is important to notice that the Out Row pin is a Struct of type EnemyStatsStruct (the
same Row Structure we assign to the EnemiesTable).
500
Retrieving DataTable values
Most of the time you will be using this node. However, in case you also need the
functionalities of the other less used node (the ones listed under Data Table category),
let’s see them in detail:
Does Data Table Row Exist: As the name suggests, taking a DataTable and the name of a row as a
parameter, it determines if that row exists. The output is a Boolean (which you can, for instance, use in
a Branch node):

Evaluate Curve Table Row: This node is for another kind of DataTable (CurveDataTables), which
unfortunately is outside the scope of our project, so we will not cover them. However, this is what the
node looks like:

Get Data Table Column as String: This exports a whole column as an array of Strings (one for each row
and the name of the column is excluded):

501
Retrieving DataTable values

Get Data Table Row Names: This exports all the row names into an array:

And this concludes how we can access the DataTables values (for each row). Now, we
are ready to deploy our DataTable to use within the game!

502
Using Construction Scripts
Using Construction Scripts
Blueprints in Unreal have two distinct graphs: Event Graph and Construction Script. The
Event Graph, for example, is what operates only at runtime. Whereas, the Construction
Script runs also within Unreal Editor and it is used to set up Blueprints when they are
constructed (spawned) for the first time. It is important to remember during game
development, that both Construction Scripts and Event Graphs are going to be used
together, but it is important to know at this point that there is nothing inherently wrong
with having a Blueprint that uses both a Construction Script and an Event Graph.
The first thing to learn about Construction Scripts is that only Blueprint Classes can have
them; Level Blueprints do not. The Construction Script is designed to execute upon the
creation of the Blueprint object, and again whenever that object is updated (only in the
editor) in some way (scaled, rotated, moved, and so on). This is quite useful when you
have objects within your game that need to be compiled prior to gameplay. In addition,
Construction Scripts also allow you to create dynamic structures, such as procedural
content generation, building paths with splines, or loading data from DataTables (and
much more).
Event Graph versus Construction Script is an important comparison to make. Event
Graphs are executed during gameplay, whereas Construction Scripts are executed when
the Class Blueprint is constructed in the level editor. Therefore, when the Class Blueprint
is moved in the level editor viewport, the Construction Script will keep executing,
because Unreal will reconstruct the object. Also, if you come from C++ (or you
eventually learn C++ in Unreal as well), keep in mind that the Construction Script is
different from the Constructor! I will not go into the details since they are C++ related,
but it is important to know in case you handle C++ in the future: The Construction Script
in C++ is implemented through a specific function, whereas the Constructor is executed
when the object is created in memory.
So, as you can see, there are many uses for the Construction Script, so it is better to know
where we can find it and modify it.
Open any Blueprint, and under the My Blueprint tab you will find under the Functions
category the Construction Script, as shown in the following screenshot:

503
Using Construction Scripts

If you double-click, you can find its implementation. It starts from a node named
Construction Script which has an execution pin, and from here you can implement any
logic you will need:

504
Using Construction Scripts

505
Start building the Hound Blueprint
Start building the Hound Blueprint
It's time to get into creating the main components for our gameplay. Here we start
building the Hound Blueprint, but we will finish it in the next chapter.
Now, within the Hound folder, we created in the previous chapter, create a new
Blueprint class. It needs to inherit from the ThirdPersonCharacter, as shown in the
following screenshot:

506
Start building the Hound Blueprint
The reason why we do this is because we have many functionalities already implemented
(including some for replication. (We will learn about that in the next chapter.) Actually,
we could inherit directly from the Character class as well, but in this way, we will get a
Hound that is already playable with a camera attached, which is cool if you want to mess
around with the Hound. However, in a real production you should avoid having
components you don’t need, so you should simplify the Hound by inheriting from
Character, and in case you want a playable Hound, then inherit from the Hound and
make it playable; so, at runtime you spawn the correct one depending on whether it will
ever be possessed by the player or not.
Then, name the newly created blueprint BP_Hound and double-click to open its editor.
First of all, it still looks like our Mannequin Character (because it is), so let’s select its
Mesh in the Components tab:

So, from the Details panel you can change the Skeleton Mesh into SK_BARGHEST, as
shown in the following screenshot:

507
Start building the Hound Blueprint

We should fix many other things in this blueprint (such as, the Animation Blueprint, the
scale, the collision, and the dimension of the capsule). Therefore, we will hold on until
the next chapter for these changes, and in this section, we will limit ourselves to the
Construction Script.
We need to create three variables of type float (which are the variables in our
EnemyStatsStruct, except for the Speed variable, which we can set directly to the
CharacterMovementComponent, named respectively: MaxHealth, BiteDistance, and
HealthRecoveryRate. Don't worry at this stage which one will be public. We will take
care of this in the next chapter:

508
Start building the Hound Blueprint

Head towards the ConstructionScript tab. Since this is a Blueprint that inherits from
another Blueprint, there is the possibility to call the Parent: Construction Script, which is
an orange node. Since the Construction Script of the ThirdPersonCharacter is empty, this
node does nothing, but let's leave it in case we change the ThirdPersonCharacter
Blueprint:

From the execution pin, we can call the Get Data Table Row EnemiesTable function with
our EnemiesTable as a parameter. Then, we can break the Out Row. We also leave us a
TODO (which is left as an exercise) about what happens if for any reason we cannot find
509
Start building the Hound Blueprint
any Row. At the moment, this is almost impossible since it is hardcoded that it will be of
TypeA, but later we might change this:

From the Break EnemyStatsStruct, we can assign each variable to its homonym. For the
Speed variable, take the Character Movement Component and use the Set Max Walking
Speed node. In the end, this is what the graph should look like:

510
Start building the Hound Blueprint

Save the BP_Hound Blueprint, since for this chapter, it is done.


To test the Construction Script you can make the variables public and place a Hound in
the world, then see if the values of the variables are the same as in the table.
In the next chapter, we will expand upon this blueprint and learn more about replication
and multiplayer.

511
Extending upon what you've learnt here
Extending upon what you've learnt here
We learnt a lot along the way in this chapter, but if you want to extend upon what you've
learnt, here are some additional exercises you can do to improve:
Another important variable for our game can be how much damage our enemy can deal with the player
(or even better, what the min. and max. values are for damage that a specific enemy can deal to the
player). Modify the EnemyStatsStruct to include this information as well and fix the EnemiesTable
to set this additional piece of data that we added properly.
What are other parts of a game besides the enemies that can benefit from using Structs to organize the
variables? For instance, since it is a multiplayer game, you could have different player characters with
different characteristics—one with more life but very low fire rate, and another one that is the opposite,
with low health, but high fire rate. Think about which variables you might need to customize your
character, create a proper Struct for those variables, and finally create a DataTable with all the
different characters.
What parts of your game could benefit from DataTables? If you don't have a game, think about what
other uses there could be for DataTables and try to create them. For instance, are you rendering
something or planning an interaction? In both cases, you can use DataTables for controlling your lights
or the rendering quality of different objects, and tweak them accordingly. For instance, you can have a
DataTable with some quality settings for Struct and each row represents a preset (such as low, medium,
and high quality).
Recreate the BP_Hound, but inheriting from the Character class.
Finish the TODO in the Construction Script of the BP_Hound.

512
Summary
Summary
So far in this chapter, we have covered what Structs, DataTables, and Construction
Scripts are and how to use them with Blueprints. We have applied them to set the main
stats of our Hound enemy. We have also looked at different ways that we can collect
various types of data to use in-game. This can be quite important when you want to
create a more specific experience for the player.
Next, in Chapter 16, Foundations of Multiplayer, we will cover a short overview of
Unreal networking. We will also cover the basics of how to import other packages for our
project so that we have more assets to work with. Next, we will create a silver bullet that
explodes on impact. In addition, we will also look at creating the player Blueprint and
give the player the possibility to shoot silver bullets with a multiplayer setup. Therefore,
we will also cover how to handle the damage and death of the Hound in a multiplayer
setup. So, let's get ready for a gnarly standoff against the Hounds and turn the page.

513
Foundations of Multiplayer
Foundations of Multiplayer
We now need to get our weapons ready and prepare ourselves against the Hounds. So
what better way to say welcome to this chapter than with some fear! Sure, single-player
games are fun, but nothing beats a good old deathmatch, capture the flag, PvP map…
right? AI can only create the feeling of additional players, but they are not as good as
playing with friends (at least not yet). Therefore, in this chapter, we're going to look at
what we need to do to set up local multiplayer experiences that will allow you and your
friends to interact with your game and share the same environment full of AI-controlled
Hounds, items, and bullets, and have a truly enjoyable experience.
In this chapter, we will learn the basics of Unreal Networking by continuing working on
our project. In particular, we will:
Give a short overview of Unreal Networking
Import other packages for our project
Create a Silver Bullet that explodes on impact
Create the Player Blueprint
Show and hide the right mesh of the player, depending on whether the character is locally controlled
Give the player the possibility to shoot Silver Bullets with a multiplayer setup
Finish setting up variables in the Hound Blueprint
Create a Hound controller
Handle the damage and death of the Hound in a multiplayer setup

As you can see, there is a lot to cover; so, let's start!

514
Overview of Unreal&#xA0;networking
Overview of Unreal networking
This is probably the first time you have come across multiplayer programming, so it's nice
to have an overview. However, I will keep it very short and synthetic because this is a
practical book, so we will learn by doing. If you need a refresher on the theory or the
exact details, this can always be found in the official documentation.
Don't worry if you don't understand this section fully, because it is a very short summary,
but it will make much more sense after we have gone through the process of creating our
game.
So, what are the important things to know?
In multiplayer games, there is a server, which can be local or remote (we will see the
difference between them in the next chapter). Then, there are different clients connected
to the server.
The server has the truth about the game, which means that what's running on the server is
the real game, the clients just replicate what's on the server. In fact, in order to make
something happen from the server for the clients, this something needs to be marked to
be replicated. If not, it will not transfer to the clients.
By default, actors have the support to be replicated (a checkbox in the Details panel).
Characters have a built-in system to replicate movement and animations, so you don't
need to worry about that. Also, single variables in actors can be replicated.
Different clients can own different actors, which means that they have the right to call
functions on them, including functions/events that sends a state to the server (for instance
the player/client that owns his/her character can call the Fire function on that character
that spawns a projectile on the server).
When there is an event on a Blueprint, it can be (in the multiplayer context):
Client: It runs on the client (only if it has been called from the server).
Server: It runs on the server (only if it has been called by a client that owns that actor/Blueprint).
Multicast: It runs on every client (only if it has been called from the server).

These functions can be reliable or not reliable. If they are reliable it means that they have
to be executed and, if the information of this function call has been lost in the network,
515
Overview of Unreal&#xA0;networking
the game has to resend it to be sure that it arrives at its destination. This is used for
important events. Not reliable means that the game will send this information, but if it
doesn't arrive, it will not do anything to make sure it arrives at its destination. This is used
for events that don't impact gameplay, such as spawning a particle effect or playing a
particular animation.
This was a short and intense overview, so let's dive into how to keep working on our
project, and this section will make more sense along the way.

516
Working towards a multiplayer setup
Working towards a multiplayer setup
We are going to adventure ourselves into a lot of code, but in the end, you will have a
better understanding of how to create a multiplayer game.
In particular, what are we going to cover in this chapter? We have a fight between our
Players and the Hounds. Of course, we want them to kill each other, and we need to
implement this mechanic. So, we need to implement how the Players can kill the Hounds
and how the Hounds can bite the Players. In this chapter we will focus on the former,
leaving the latter for the next chapter. Lastly, before diving into the code, we need to
prepare some more assets for our game.

517
Preparing the assets
Preparing the assets
When we talked about creating the project back in Chapter 14, Animating the Hound I
said that we were going to import the first-person assets into this project. First of all, let’s
understand why.
By design, our game is in the first person, meaning that when you play you see your
characters as if in first-person. However, when you meet your friend, who is playing in
first-person as well, you don’t want to see floating arms, but rather a full character.
Therefore, we build our project around the ThirdPerson template. Now, we need to
make the game first-person, but only for the playing person, whereas all the other players
should see a ThirdPerson character.
Thus, we need to import the first-person assets. We can do that by creating an empty
project with the first-person template. Then, in this second project right-click on
FirstPersonCharacter and select Asset Actions | Migrate..., as shown in the following
screenshot:

518
Preparing the assets

As a result, Unreal will gather all the references to this asset:

519
Preparing the assets

520
Preparing the assets
Once you press okay, Unreal will ask where to migrate (/export) the asset along with
all its references. We can select the Content folder of our MultiplayerGame. Then, a
popup should tell you that the migration happened successfully.
Alternatively, you can import the FirstPerson package in another way, by clicking on
Add in the Content Browser and then Add Feature or Content Pack..., as shown in the
following screenshot:

521
Preparing the assets

522
Preparing the assets
Then, you can select the First Person template:

However, this template is slightly different from the one you import in an empty project.
For instance, it doesn't have the projectile, and the code to fire as the First Person
character is slightly different. Thus, I suggest you do as before and create an empty
project, so you will not need to recreate the projectile and you can easily follow this
chapter.
Then, we need some additional assets if we want to customize our look. For instance, I'm
going to take some effects from the Infinity Blade Effects package (you can find it here:
https://www.unrealengine.com/marketplace/infinity-blade-effects), which is free:

523
Preparing the assets

However, I will always specify if an asset that I'm using or referencing comes from a
different package from the one we have imported so far (Quadruped Creatures, First, and
Third Person templates).
Another interesting package, in case you want to change the weapon for your character,
its this free FPS Weapon Bundle (you can find it here:
https://www.unrealengine.com/marketplace/fps-weapon-bundle), which contains many
interesting weapons for your Hound Hunt:

524
Preparing the assets

525
Silver Bullets
Silver Bullets
Before adventuring into multiplayer programming, we need to create some terrible bullets
to use against the Hounds that are invading our territory.
Thus, to keep our project organized, let’s create a folder in the content browser, and call
it PlayerCharacter. In this folder, we can place all the assets related to our Player
Character, including these Silver Bullets.
In our First Person Template, we have a FirstPersonProjectile (at FirstPersonBP |
Blueprints | FirstPersonProjectile). We can right-click on it and duplicate it. Then, we can
move it to the PlayerCharacter folder. Here, we can rename the Blueprint SilverBullet.
Double-click on the Blueprint asset to open its editor. If you want, you can customize the
look, so that it looks more "silver" than a like yellow ball! By now, you should be able to
do it by yourself. Once you have finished creating your bullet, continue reading.
The next step is to change the code. Currently, it applies a physics force to entities that
have physics simulation activated (and bounces too!). Instead, we just want to make the
projectile hit the first object, make a little particle effect, and disappear. Therefore, erase
all the graph after the Event Hit, to leave just the event. From the event, we just use the
Spawn Emitter at Location, and use the P_ImpactSpark effect from the Infinity Blade
Effects package (otherwise, you are free to choose the one that you prefer or create your
own); for the location, we will use the Hit Location from the Event Hit. Afterward, we
can destroy the bullet, and we will have had done with it:

526
Silver Bullets

527
The Player Blueprint
The Player Blueprint
In this section, we will create and start building our Player Blueprint. In particular, we
need to make it so that it looks like it is in the first person if the player is using this
character, but in the third person to all the other players. Then, we give the player the
possibility to shoot in a multiplayer setup. However, we will finish the implementation of
this Blueprint in the next chapter. Let's get started!

528
Setting the Player Blueprint up
Setting the Player Blueprint up
The first thing we need to do to create our Player Character is to duplicate the
FirstPersonCharacter that you find at the FirstPersonBP | Blueprints |
FirstPersonCharacter location. So right-click on it and then Duplicate; then move it
inside our PlayerCharacter folder. You can rename it just Player.
Alternatively, you can inherit from the FirstPlayerCharacter, by creating a
Blueprint and select as a parent the FirstPersonCharacter, as shown in the
following screenshot:

529
Setting the Player Blueprint up

However, in this case, it is better to make copy since we haven’t created the
FirstPersonCharacter, so we don’t need all its features, and some we are going to
erase.
Once you open the Player Blueprint, we need to get rid of some graphs. In particular,
530
Setting the Player Blueprint up
since this is not a VR game, or at least since VR is outside the scope of this book, we can
easily erase all the graphs associated with the BeginPlay event, that is the ResetVR
event. Erase also all the Fire event part, since we are going to replace it with a slightly
modified version. Erase the UsingMotionController variable as well. Finally, erase from
the Components Tab all the VR-related stuff, thus dispose of the L_MotionController
and R_MotionController components and their children.
Then, optionally (but it is better if you do), rename Mesh2P in the Components tab
Mesh1P, in order to keep everything tidy. Now, we are ready to start to customize our
Player.
Even though we are in first-person, as we have seen earlier, the other Players will see this
one as a third person. Thus, we need to include the third-person character in this
Blueprint. Select the Mesh component (and not Mesh1P) as shown in the following
screenshot:

In the Details panel, click the drop-down menu next to the Skeletal Mesh variable, and
select SK_Mannequin as shown in the following screenshot:

531
Setting the Player Blueprint up

As you can see, we have added the character, but it is still and it doesn’t move.
Therefore, let’s assign its Animation Blueprint, so select ThirdPerson_AnimBP from the
drop-down menu next to the Anim Class, as shown in the following screenshot:

532
Setting the Player Blueprint up

Now, if you head towards the Viewport, you may notice that the ThirdPerson is
present, but it is a bit off. So, in the Details panel, let's give it a location on the z-axis of -
80 and a rotation always on the z-axis of 270. As a result, we will be able to position the
ThirdPerson character properly, as shown in the following screenshot:

533
Setting the Player Blueprint up

Now, it's time to code!

534
Hiding the right mesh
Hiding the right mesh
The first thing to do is to hide the mesh that we don't need. To do this, we will use a node
called isLocallyControlled, which returns a Boolean depending on whether this
character is controlled by the Player who is playing in this instance of the game. Thus,
let's create a Begin Play event, since we have erased it before, and use a Branch node
depending on the Boolean value of this isLocallyControlled node, as shown in the
following code:

Next, depending on if we are in the True or False branch, we need either to hide the
Mesh component or the Mesh1P. In particular, we can hide them by using the
SetVisibility node. If we are on the True branch, we hide the mesh (since it means that
this character is locally controlled, so the player in this instance is controlling and we
need to show a first-person and not a third one); otherwise we hide the Mesh1P (since it
means that this character is not the controller locally, so the player in this instance of the
game should see it as a third-person character). This is the code:

535
Hiding the right mesh

Now, when we play the game in a multiplayer environment, we have the right mesh
selected. Next, we can fire!

536
Firing Silver Bullets
Firing Silver Bullets
The next thing in the to-do list is to add the possibility for our Player to shoot Silver
Bullets. So, let’s start by creating a Fire event (it should already be in the Project
Settings set as Input; otherwise, be sure to create it as we did back in Project 1):

If you have inherited the Player class from something else, it is probably also a good idea
to check that this event overrides the parent implementation:

From now on, we are going to be very specific which function runs on the client and
which one on the server. Any input from the user runs on the client, so when the Player
presses Fire, we are still on its instance of the game.
In our FirstPerson template, we have a montage that plays a shoot animation for the first
person. This is perfect because, since we are still on the client, we can play this animation
without showing it to the others (since they will see this player as a third-person character
and the Mesh1P is hidden).
We can get the Anim Instance from the Mesh1P and play the montage, as shown in the
following code:
537
Firing Silver Bullets

Now, it’s time that we pass to the server. In fact, anything that is not decoration and
affects the world should run on the server. Thus, let's create a custom event, and name it
Server_SpawnProjectile. In the Details panel be sure to check that Replicates is set to
Run on Server, so this function will run on the server (but for security reasons it has to
be called from a client that owns or controls that Blueprint; in our case this is true since it
is the Player character that the Player is moving when he/she fires). Moreover, check that
it is Reliable, since it is an important event and it cannot be missed. (Imagine how
horrible it would be to press fire and, because of a glitch, no bullet appears to save you
from a giant Hound!).

538
Firing Silver Bullets

Then, from the end of the previous function, we can call this newly created event, as
shown in the following screenshot:

From the Server_Spawn Projectile, we need to spawn our Silver Bullet. So create a
SpawnActor node and select our Silver Bullet for the Class pin. Then, in the
Transform we can place a very similar code to the function we have erased. Basically,
we get the rotation from the camera, whereas the position is from the end of the gun, plus
a little offset that has been rotated in the same direction of the camera. (You can look at
539
Firing Silver Bullets
the code below to clarify better how it works). Then, for the Collision Handling
Override pin, we can select Try To Adjust Location, Don’t Spawn if Still Colliding.
This means that we do our best to spawn the bullet, but if the Player's gun is inside a wall,
we want to prevent it from spawning a projectile. So, the final code for spawning is the
following:

Next, we need to run some decoration code, which can be audio effects or the animation
that our ThirdPerson character has shot (since we already played it for the
FirstPerson one). Therefore, from the server, we need to communicate to all the
clients, and that can be done with a Multicast function.
Create a new custom event and name it Multicast_PlaySound. In the Details panel, be
sure to select Multicast for Replicates. Unless sound is a vital strategic step in your
game, then we can make this multicast NOT Reliable, since if we miss the sound it’s not
a big deal and we leave the network free for more important information:

540
Firing Silver Bullets

Then, as before, we can call the Multicast_PlaySound function from the end of the
previous event, after the SpawnActor, as shown here:

Finally, from the Multicast, we can play the sound of the shot (which is included in the
First Person template) and it is called FirstPersonTemplateWeaponFire02. We can
play it with the Play Sound At Location node and use this actor location:

541
Firing Silver Bullets

Now we can save our Player Blueprint, since we have finished, for the time being. In
fact, we will continue to work on this Blueprint in the next chapter, in which we
implement how the Player can recover health and how it can take damage from the
Hound(s).
We have our Player able to shoot Silver Bullets, which travel against the Hound(s) and
create a big explosion, thus it’s time to revise the BP_Hound to take in the damage and
fix a couple of things we have left from the previous chapters.

542
Hound Blueprint
Hound Blueprint
In this section, we will complete what we have left suspended in the Animation Blueprint
for the Hound (even though, we will need to wait until next chapter to have really
finished with the Animation Blueprint of the Hound).
Then, we will create the AI controller for the Hound, so we can create a function for its
death, but the real function of the AI controller will be clearer in the next chapter.
Finally, we will implement how the Hound can get damaged by the Silver Bullets thrown
at it by the Players, and eventually die if its health reaches zero. So, let’s get started!

543
Setting variables in the Animation Blueprint
Setting variables in the Animation Blueprint
If you remember, in Chapter 14, Animating the Hound, we left some variables to set in
the Animation Blueprint for the Hound. Now, it's time to finish that part.
Open the BP_Hound and let's make the Health and the BiteDistance public (this last
one will be used in the next chapter) by opening the eye next to their names:

Then, let's add a Boolean variable and call it bShouldAttack and make that public as
well:

544
Setting variables in the Animation Blueprint

Head to the Animation Blueprint for the Hound and use a Try get Pawn Owner node
along with a pure cast to convert it to our BP_Hound. From there, we can retrieve the
Should Attack variable, and set it in its homonym variable name for the Animation
Blueprint, as shown in the following screenshot:

545
Setting variables in the Animation Blueprint

Then, always from the BP_Hound we have found, let’s get its Health and check if it is
less or equal to zero. The result is a Boolean that we can set in the IsDead Boolean
variable of the Animation Blueprint. This is how the graph should look in the end:

546
Setting variables in the Animation Blueprint

Save the graph, and leave it be for the moment. We will finish it finally in the next
chapter.

547
Hound AI controller
Hound AI controller
The next thing we need to create, in order to support the death of the Hound properly is
an AI controller with a function that runs on the server for the death. We will understand
the role of this AI controller in the next chapter.
In the meantime, let’s create a new AI controller (create a new Blueprint that inherits
from AI Controller):

548
Hound AI controller

Rename it BP_HoundController and double-click on it to open its editor.


Create a new custom event named Server_HoundDie; of course, set the Replicates to
Run on Server. Then, get the Brain Component (you don't need to know what it is just
yet, but every AI Controller has it, so you can just get it as with any other variable, even
if it is not listed among the variables). From it, you can use a node called Stop Logic and
give as a reason Dead. After that, just call Destroy. As a result, once this function is
called, our controller will stop the logic (which will be a Behavior tree that we will create
in the next chapter) and then, destroy itself:

549
Hound collision
Hound collision
Finally, we can work on the BP_Hound Blueprint. In this section, we need to implement
that the Hound can take Damage from the Silver Bullets.
First of all, let's create a Sphere Collision named BiteCollision (we will need this in the
next chapter). Then, you need to attach it to the Head of the Hound. So, in its Details
panel, change the Parent Socket into the BARGHEST_-Head bone, as shown in the
following screenshot:

550
Hound collision

Then, change its location on the x-axis to 25, and its scale on all the axis to 1.5, and in
551
Hound collision
the end the Sphere should look like the following in the viewport:

Now, create a Capsule Collision named BodyCollision (we need this to detect if
something hits the Hound, since Character Capsule doesn't cover all the body of the
hound, so we will use it only to move). We need to attach this Body Collision to the
BARGHEST_-Spline2 bone by setting the Parent Socket, as shown in the following
screenshot:

552
Hound collision

Use the following settings to position and dimension the capsule properly:
553
Hound collision

As a result, this is what it should look like on the Hound:

554
Hound collision

And we have concluded with the Collisions. Now, it's time to code again!

555
Hound can get hurt
Hound can get hurt
In this section, we are going to create the possibility of the Silver Bullets hurting the
Hound, by giving the Players a chance to win.
From the Body Collision component, let’s create an Event Hit as shown in the following
screenshot:

Remember that this Hit event will run on the server.


Next, we need to cast the Other Actor to a Silver Bullet to check if it is really a Silver
Bullet. If so, we need to decrease the Health. How much? Well, this depends on your
game balance. For now, I'm going to use a hardcoded value of 25, but I leave it as an
exercise to include this value in some data structure we learned in the previous chapter to
adapt and balance the game better. For instance, you could create a DataTable for the
different types of bullets and how much they hurt the Hounds:

556
Hound can get hurt

However, right now this value of Health just decreases on the server, so even if the
Hound dies, it only does so on the server. Instead, we can set the Health variable so that
it should replicate, which means that if I change its value, the change is propagated to all
the rest of the network. Select the Health variable and in the Details panel, you can
change it so it is replicated. (Of course, there are other settings that determine when this
value should be replicated, but let’s leave it as its default):

557
Hound can get hurt

(If you want, you can also replicate the bShouldAttack variable, which we will use in
the next chapter).
As you can see, the graph now changes, because in the corner of the variables that get
replicated there is a symbol indicating that the variable is replicated:

558
Hound can get hurt

As the next step, we need to check if the Health is less or equal than zero, and use a
Branch to separate the execution.

If the Health is less or equal than zero, then we need to kill the Hound. So, from the
True branch we get the AI Controller (with the node Get Controller) and cast it to
BP_HoundController. If the cast succeeds, we call the Server_HoundDie function we
created earlier (the one to stop the logic and destroy the controller):

559
Hound can get hurt

Afterward, we destroy the BodyCollision component (because we don't want this Event
Hit to be called again after the Death of the Hound) and then we wait 10 seconds
(because the Animation Blueprint needs the time to play the Death Animation) before we
Destroy the Hound:

If on the other hand, the Hound is not dead yet after this hit, we need to spawn a little
effect to give visual feedback to the player that the Hound has been hit. So, let's create a
560
Hound can get hurt
Multicast function named Multicast_SpawnHitEffect. It doesn't need to be reliable, but
it needs to be of type Multicast. Moreover, we need a Location where to Spawn the
effect, so let's add a Vector as an input of this event (by pressing the + button), as
shown in the following screenshot:

Then, from the Multicast, we use Spawn Emitter at Location (I'm using
P_TrollDeathImpact from the Infinity Blade Effects package), and its location is passed
from the event.
From the False branch of the previous function, we call the Multicast function, and we
pass as location the Hit Location (we can retrieve it from the Hit variable/structure
which we need to break and retrieve the Hit Location). So, this is what the graph should
look like:

561
Hound can get hurt

Now, you should really congratulate yourself because we just implemented the possibility
to hit the Hound! And that is all for this chapter.

562
Extending upon what you&#x2019;ve learned here
Extending upon what you’ve learned here
Since we are in the middle of the game creation, there are no particular exercises.
However, I will present some points concerning where to start to extend what you've
learned:
Use a DataTable for different types of bullets and use different damage for the Hound based on the type
of bullet.
Make the Silver Bullet look more like a Silver Bullet. For example, you can change the shape or the
material of the bullet.
Replace the Player gun with a real one, for instance from one of the free packages I showed you at the
beginning of the chapter.
Find some Animations for the Third Person Character so it can hold a gun and shoot as well. You will
need to Create a Montage or Change the Animation Blueprint to do this.

563
Summary
Summary
In this chapter, we have seen how to work on a multiplayer setup, and we have chosen a
practical approach to learning how to do it. In particular, we have created a Silver Bullet
that explodes when it hits something; we have empowered the Players with the possibility
to shoot and see each other properly. We have created a Hound Controller, finished
assigning the variables in the Animation Blueprint for the Hound, and implemented the
Hit on the Hound and its Death!
In the next chapter, Chapter 17, Extending the Multiplayer Setup, we will keep working
on this, and implement how the Hound can bite back at the Player! Because, let's face it,
things needed to be more dramatic! Therefore, we will learn how to implement a
recovery system for the Player as they receive damage from the Hound. Of course, we
will also implement a recovery system for the Hound as well, along with the possibility
for the Hound to bite the Player by using the Animation Notify and Animation Blueprint
to trigger the moment in which the Hound bites.

564
Extending the Multiplayer Setup
Extending the Multiplayer Setup
Welcome to Chapter 17, Extending the Multiplayer Setup, and the final stretch! Here, we
will extend upon what we have done in the previous chapter. In particular, we will do the
following:
Implement a recovery system for the Player
Give the player the possibility to receive damage from the Hound
Implement a recovery system for the Hound as well
Give the Hound the ability to bite the player
Use animation notify and animation blueprint to trigger the moment in which the Hound bites
Give a chasing behavior to the Hound
Trigger the chasing behavior from the Hound Controller

So, let's get ready!

565
Finishing the player blueprint
Finishing the player blueprint
Continuing from the last chapter, we have two things left to do in the player blueprint.
We need to set a Recovery Health System, and find a way to take damage from the
Hound. Let's begin!

566
Recovery health system
Recovery health system
To make a Recovery Health System, we first need a Health variable on which we can
store the life of the player and, of course, it will also be used to take damage and check
the Death Conditions. So, let's create a Health variable of type float:

As we understood in the previous chapter, we need to replicate this variable. Moreover,


we need to give it default values (unless you have a DataTable for the player—in that
case, you can assign its value from the Construction Script, like we did for the Hound). A
default value of 100 will be fine for now. This is what it should look like in the Details
Panel:

567
Recovery health system

Next, we need a HealthRecoveryRate variable, otherwise we don't know how often to


recover health. Create another type float variable:

568
Recovery health system
This needs to be replicated as well, and can have a default value of 1, as shown in the
following Details panel:

Now, from the end of the graph of the Event Begin Play (which we split into two
branches—which one to use depends on which mesh you hid in the previous chapter), we
make a Branch node. The condition is that the HealthRecoveryRate is greater than zero,
otherwise there is no point in continuing for the recovery procedures. Even if you want to
make a hardcore level in which the HealthRecoveryRate is zero in the future, you can do
it without encountering errors or performance pitfalls. This is the graph so far:

569
Recovery health system

If the condition is True, then we use a Set Timer By Event node, which allows us to call a
function after a certain period of time. To set the time, we can divide 1 by the
HealthRecoveryRate (which we are sure is different from zero, since we are in the
branch in which the HealthRecoveryRate must be positive, and so greater than zero). In
this way, we can obtain the time before we recover one of Health. This means that a
HealthRecoveryRate of 1 recovers 1 HP (Health Point) every second, a HealthRecovery
of 2 means 2 HP every second (1 HP every half second); and a HealthRecoveryRate of
0.5 means 0.5 HP every second (1 HP every 2 seconds).
This is what the node looks like:

570
Recovery health system

If you try to compile now, you will get an error, because we still need to specify which
function we want to call when the time expires. Moreover, we want this function to be
called every time this timer gets to zero.
Hence, the first thing we set to true is the Looping checkbox on the Set Timer By Event
node.
Then, we create a custom event and call it RecoverHealth. By doing this, we can connect
the red pin from the top-right corner of the event inside the Event pin of Set Timer By
Event, as shown in the following screenshot:

571
Recovery health system

Finally, from the RecoverHealth event, we can just increase the Health variable with a
Float Increment node. This is the full code for the Health Recovery of the Player:

572
Recovery health system

Now that we have Health and a way to get it back, let's see how we can lose it.

573
Taking damage
Taking damage
For our Player to take damage, we need to expose a function that will be called from the
Hound. So, let's start by creating a new event named TakeDamage with a float parameter
as input named Damage. As a result, the Hound will be able to specify how much damage
it can deal to the player. The following screenshot shows us what the event should look
like in the Details Panel:

Then, from the event, we simply subtract the Health from the Damage parameter and set
it back to the Health variable, as shown in the following screenshot:

574
Taking damage

Next, we need to check if our Health has reached zero, which we can do with a Branch
node:

Finally, we can implement our Player Death on the True branch, or better yet you should
be able do it on your own by now—this is left as an exercise. However, I'm going to use a
Print String node so that the game is still playable and shows me that I lost. On the False
branch, we can do what we did with the Hound and by using a Multicast, implement a
nice Hit effect. I will leave this as an additional exercise for you. However, I will leave
575
Taking damage
you with the structure on which you can implement you exercise:

This is all for Take Damage. Now, we need to see how the Hound can call this function.

576
Hound attack
Hound attack
As for the Hound, we have two things left to do: make it bite the player to inflict damage
and eventually chasing him/her so that it can bite them. So, let's start by implementing the
terrible bite. But first, like we did for the Player, we need to implement the Health
Recovery Behavior.

577
Recovering health for the Hound
Recovering health for the Hound
Recovering health for the Hound is very similar to what we did with the Player Health
Recovery. Moreover, we already have the HealthRecoveryRate and Health variables, so
we don't need to create them.
From the Event BeginPlay (create it you don't have it, since we haven't use it so far), we
first check whether the HealthRecoveryRate is greater than zero:

Then, the rest is exactly like the Player recovery system. From the True branch, we use
the Set Timer By Event node, calculate the time as the inverse of the
HealthRecoveryRate, and attach a looping event that increments the Health variable:

578
Recovering health for the Hound

This concludes the Health Recovery System for the Hound. Now, it's time to implement
the bite!

579
Biting event in the Blueprint
Biting event in the Blueprint
For the Bite behavior, we start from the end and proceed backward, like we did so far. In
fact, we have implemented the Take Damage function on the Player, and now we are
going to see which function is going to call it.
In particular, we are now going to implement a function that, in the moment in which the
Hound has to bite, checks to see if there is a player in the bite collision and applies
damage to him/her.
Open BP_Hound and create a new event. Call it Server_Bite. Of course, Replicates
needs to be set to Server. Then, get the BiteCollision and call the GetOverlappingActors
node. We can use the Player blueprint as the Class Filter so that we can only find
Players. The code for this is as follows:

From the GetOverlappingActors node, we get the first element of the Array and then we
check if it is valid, as shown in the following screenshot:

580
Biting event in the Blueprint

581
Biting event in the Blueprint
Unfortunately, even if we used this as a filter the Player, the return value is just an Actor,
so we need to cast it to the Player. Then, we can call the Take Damage function.
Regarding the damage that the Hound should apply, it depends on how you structured
your Hound. For instance, you can have the damage inside the DataTable and then load
the value on the Construction Script. This would be a cleaner way to do it. I leave this as
an exercise to you. I'm just going to hard-code a value of 25, as shown in the following
screenshot:

This function is now done!

582
Biting from the Animation Blueprint
Biting from the Animation Blueprint
Now, we have this amazing function that states that when the Hound needs to bite, it
applies damage to the Player; but how we can determine when the Hound should bite?
Well, we need to check when, during the animation of the Hound biting, at which
moment it bites and trigger this function at that moment. We will use the Animation
Blueprint of the Hound one more time, which will be the last time.
But first, we need to create an animation notification, which is a way for an animation to
tell the Animation Blueprint that a certain point of the animation has been reached. In
particular, we need to open the BARGHEST_JumpBiteAggressive animation. This is
what the editor should look like:

583
Biting from the Animation Blueprint

Keep the animation loop in mind, as well as the fact that we need to choose the frame at
which the Hound bites. For instance, frame 14 seems very promising, so let's pause the
animation and select it:

584
Biting from the Animation Blueprint

Next, in the Notifies timeline (just below the viewport) right click. There, you have the
option to create a new Animation Notify (Add Notify | New Notify...), as shown in the
following screenshot:

Then, Unreal will prompt you to insert a name. We will call it BiteNotify:

585
Biting from the Animation Blueprint

Once you pressed Enter, the Animation Notify will appear in the Notifies timeline, as you
can see in the following screenshot:

Let's head back to the Animation Blueprint. In particular, we need to open the Event
Graph. There, we now have the possibility to create an event for our BiteNotify, as
shown in the following screenshot:

586
Biting from the Animation Blueprint

This is how it appears in the graph:

Next, by using Try Get Pawn Owner once more, along with a cast, we can obtain the
BP_Hound. From it, we can call the Server_Bite function!

It looks like we're done, but if we press play, the Hound doesn't move or chase the player.
We need to create a Behavior Tree for this Hound and within it provide a way to make
the bShouldAttack variable of the Animation Blueprint become true (based on the
587
Biting from the Animation Blueprint
bShouldAttack variable in the BP_Hound and its BiteDistance).

588
Chasing the Player with a Behavior Tree
Chasing the Player with a Behavior Tree
One last thing to do for our Hound is to create a Behavior Tree for it. Don't worry—it will
be easier than the last Behavior Tree we created since the behavior here is much simpler.
To start, let's create a folder within the Hound one, and name it AI. Here, we will place
all the AI-related assets.
First of all, we need a Blackboard where we can store the data for the Behavior Tree. In
this case, we just need a reference to the player that the Hound is currently chasing it. So,
let's create a Blackboard asset and name it BB_Hound. Then, within the Blackboard, add
a variable of type Object (of the Player class, like we did in the previous project) named
Player, as shown in the following screenshot:

589
Chasing the Player with a Behavior Tree
Next, we create our Behavior Tree and name it BT_Hound. Open it, and be sure to assign
the BB_Hound Blackboard to it:

Next, create a new Task. In fact, we need to have a task that searches for the nearest
player. Remember that, in a multiplayer context, there are multiple players. Therefore,
the Hound has to target the player that it is closest to.
We can name this task BTTask_FindClosestPlayer. We need to add a couple of variables.
The first is the PlayerKey, which is a Blackboard Key Selector that will hold the Player
reference. The second is an Actor Class (select Actor as a type of variable, then instead
of reference, choose class) named PlayerClass. In this way, we can be more general and
ask the Task which class of player to look for. Both of these variables need to be public:

From now on, the code will have many wires and pins, so in the preceding screenshot, I
did my best to reorder the blueprint and make it as clear as possible. In any case,
remember that you can have a look at the project files if you are in doubt.
Let's start by overriding the Event Receive Execute AI. By using the Player Class, we
can search for all Actors of a Class with the Get All Actor of Class node, as shown in the
following code:

590
Chasing the Player with a Behavior Tree

Next (I use a Sequence node to make the graph clearer), we assign the first element of
this array to the Player variable that's referenced by the Player Key. Then, I start to loop
around the array to find which one is the closest:

In theory, you can skip the first element of the array, but since we don't have many
players or many Hounds or performance problems of any kind at the moment, I will
repeat the check, even for the first element of the array. Also, I re-calculated the distance
from the currently selected player so that I can store it inside a variable instead. The same
goes for the player that I use the Blackboard for every time, instead of a temporary
591
Chasing the Player with a Behavior Tree
variable. Doing all of these improvements in Blueprint would have been a big mess of
wires, but in case you have performance issues (not in our project, but if you are working
on a big project), keep this in mind.
Now, we need to get the distance from the Hound to the current lowest distance Player
(the nearest) and the distance from the Hound and the next Hound in the loop:

Then, we need to compare this distance. If the distance with from the new is less, then we
can assign the new player to be the lowest distance away:

592
Chasing the Player with a Behavior Tree

Finally, don't forget to finish the task (Finish Execute node) with a success (I used a
sequence to help clarify the screenshots):

Now, the task is ready. However, we also need a service to check whether or not the
Hound should attack. Thus, let's create a new service for the Behavior Tree and name it
593
Chasing the Player with a Behavior Tree
BBService_CheckIfShouldAttack.
Here, we just need a single variable, the PlayerKey, of type Blackboard Key Selector,
which needs to be public:

Next, override the Event Receive Tick AI and cast the Controlled Pawn to our
BP_Hound:

Then, we get the distance from the BP_Hound and the Player (by using the Blackboard),
which is the one that is currently targeted:

594
Chasing the Player with a Behavior Tree

From the BP_Hound, we can retrieve the BiteDistance and check whether or not it is
greater than the distance from the Hound and the targeted Player:

595
Chasing the Player with a Behavior Tree

Finally, we can set its value to the Should Attack variable (always from the BP_Hound) if
the cast succeeds:

596
Chasing the Player with a Behavior Tree
As a result, if the Hound is closer than the Bite Distance to the Player, the Should Attack
variable will be true, or false otherwise.
Now, it's time to build our Behavior Tree. Start by dragging a sequence node from the
root, and then attach our BTTask_FindClosestPlayer task (of course, we need to assign
the Player value to the Player key in the Blackboard, and for the Player Class, the Player
Blueprint we created). This is what the Behavior Tree should look like:

Next, we can add MoveTo as the next task of the sequence and give the Player as the
BlackboardKey:

597
Chasing the Player with a Behavior Tree

Then, to our sequence, we need to attach our Service, again by assigning the Player Key
to the Player Blackboard value. The tree should now look as follows:

598
Chasing the Player with a Behavior Tree

Right now, the tree works, but once a Hound has locked in (targeted) a player, it will
chase them until either the Hound dies or the Player does. However, we can slightly
change this behavior and reevaluate which is the closest player again in case the chasing
lasts more than a certain period of time. Thankfully, we have a built-in decorator for that,
but a decorator cannot be below the root node, so we need to add an additional sequence
node. This is our final tree:

599
Chasing the Player with a Behavior Tree

You can also rearrange the node so that the tree looks like a bit more ordered, like so:

600
Chasing the Player with a Behavior Tree

Save the Behavior Tree. Now, we just have one more thing to do. We need to run this
601
Chasing the Player with a Behavior Tree
Behavior Tree! So, let's open the Hound Controller, and in the Event BeginPlay, we need
to Run Behavior Tree, as shown in the following screenshot:

Lastly, we need to head back to the BP_Hound to assign this controller. So, in its Details
Panel, under the Pawn options, we need to select that the AI Controller Class is
BP_HoundController. Also, if you are planning to do a spawning system, later on, set the
Auto Possess AI to Place in World or Spawned. Finally, to be sure that it doesn't get
controlled by the player (at least not by default), set Auto Possess Player to Disabled
(which should already be the default value). This is what everything should look like in
the Details Panel:

Save everything and….. **drumroll** …. DONE! Yes, we basically finished the whole
core of the game! Isn't that incredible?
602
Chasing the Player with a Behavior Tree
Well, there is still a little bit to do to improve and/or make it actually playable, but the
hard part has been done. So, take a rest before launching yourself into the next chapter!

603
Extending upon what you've learned here
Extending upon what you've learned here
Once again, this chapter was really intense in terms of code. As usual, I left some
exercises for you directly in the text:
Implement a proper Player Death, either by triggering a proper UI, propagating correctly to the
Server/Clients, and maybe by showing some animations
Implement a Nice Hit Effect on the Player when the Hound bites the Player
Restructure the EnemisDataTable so that you have a value for the damage dealt with the Player so that
you can use it correctly in the code
Optimize the BTTask_FindClosestPlayer with the information given in the infobox

604
Summary
Summary
In this chapter, we have done quite a lot. So, let's recap. In this chapter, we implemented
a Recovery System for both the Hound and the Player. We also have implemented how
the Player can take damage. We started with the take Damage function on the player,
which is called from the Bite function from the Hound. By using an Animation Notify
and the Animation Blueprint, we were able to trigger when the Hound should bite.
Finally, we saw how we can create a Behavior Tree, along with a custom Task and a
custom Service for chasing the Player. This concludes the core of our Multiplayer game.
In the next chapter, we will look at a couple of additional things so that we can improve
our game and make it playable with a friend.
Next, in our penultimate Chapter 18, Adding Additional Features, we will understand the
difference between Listen and Dedicated Servers. We will also look at how we can fix up
some bugs in our game. Then, we will learn how we can connect with friends and play
together. Lastly, we will look over some ideas about how we can expand upon what we
have already done. So, take a much-earned rest and get ready for the final parts of our
journey.

605
Adding Additional Features
Adding Additional Features
We have reached the penultimate chapter. At this point, we're about to wrap up our third
project and begin finishing our journey.
In this chapter, we will complete our third project, and we will cover the following topics
Understanding the difference between listen and dedicated servers
Fixing up some bugs in our game
Learning how we can connect with friends and play together
Getting some ideas on how to expand upon what we have done previously

So, let's start!

606
Listen vs dedicated server
Listen vs dedicated server
In this section, we will explain the difference between a listen server and a dedicated
server:
A Dedicated Server is a standalone server that does not require a client; this means that it can have zero
clients connect. It runs separated from the Game client and is mostly used to have a server running that
players can always join/leave.
A listen server is a server that is also a client, and this is why it is called Listen Server. As a result, the
server will have always itself connected, so it will always have at least one Client. If this client
disconnects, the server shuts down. Since this server is also a client, it will require a rendering part
(including UI), and have all the classes to control the Client (for example, the Player Controller). The IP
to connect to this server is the same as the client.

For this game, we are going to use Listen server, to keep things simple.

607
Playtesting the game
Playtesting the game
Before we move on, we need to test whether everything works as expected or there are
bugs. Actually, there are a couple of things that we forgot, but that's not a problem,
because the point of this section is to explain to you how to individuate a bug through the
use of playtesting and how to fix it.

608
Preparing the Map
Preparing the Map
We never created a map for our game to use. So I duplicated ThirdPersonMap,
renamed it MyFirstMultiplayerMap, and moved it into a Maps folder that I just
created.
From the map, remove the Third Person Character, and
duplicate NetworkPlayerStart, as shown:

Finally, you can place some Hounds in the map if you like.

609
How to test
How to test
But how do we test a multiplayer game? There is a nice way to do it in the editor. You
just need to go in the Play options (the little arrow next to the Play button) in the Top Bar
menu and insert 2 with the slider next to Number of Players:

Now we are ready to press play and fix all the bugs that we encounter!

610
Fix #1 &#x2013; Adding a Game Mode to spawn the right Player Class
Fix #1 – Adding a Game Mode to spawn the right Player
Class
Now when you press play, a couple of players are spawned. However, we never said to
the game to Spawn our Players Blueprints.
We can fix this by creating a new game mode. To achieve this, create a new Blueprint (in
an appropriate folder) and make it inherit from GameModeBase, as shown:

611
Fix #1 &#x2013; Adding a Game Mode to spawn the right Player Class

We can rename it MultiplayerGameMode. Then, open up its blueprint editor, and in the
Details Panel, select the Player Blueprint as the Default Pawn Class:
612
Fix #1 &#x2013; Adding a Game Mode to spawn the right Player Class

613
Fix #1 &#x2013; Adding a Game Mode to spawn the right Player Class
Finally, in our Map, we need to change the World Settings, so that we can use the
MultiplayerGameMode that we have just created:

If we press Play again, now the right class is spawned as Player.

614
Fix #2&#xA0;&#x2013; Second Player cannot see Projectiles
Fix #2 – Second Player cannot see Projectiles
If we shoot with the second player (remember that the first one is the server in local
server), they are not able to see their own silver bullets, even if the first person can.
The problem is that we create the Silver Bullets on the server, which is great, but they are
not replicated back to the clients. Thus, we need to open the Silver Bullet Blueprint, and
in its Details panel select the Replicates checkbox:

If we press Play now, the second player is able to see their own Silver Bullets.

615
Fix #3&#xA0;&#x2013; The Hound is not moving
Fix #3 – The Hound is not moving
This problem occurs because the MoveTo node in the Behavior Tree relies on the
NavMesh, but we haven't created one.

So, let's drag a NavMeshBoundsVolume into the map and scale it so it fills up the map.
If you press P, you are able to see the NavMesh that has been generated, so you can be
sure that it covers the map:

Now, if you press Play, the Hound moves as it should.

616
When the Second Player shoots (not the server) the bullets are straight independently of the position of the Gun
Fix #4 – When the Second Player shoots (not the server)
the bullets are straight independently of the position of
the Gun
This happens because the proper orientation of the gun doesn't live on the server, and
when we Spawn the Silver Bullet on the server, we calculate the Transform there. We
could fix this by replicating it on the server, but an easier solution for this small project is
to modify the code slightly.
On the Server_SpawnProjectile event, we need to add an input of
the Transform type:

Then, we can move the calculation of the Transform on the Client and pass it to the
server. This is how the final graph should look:

617
When the Second Player shoots (not the server) the bullets are straight independently of the position of the Gun

And the problem has been fixed!


I didn't find any other problems, so let's move on. In case you find a problem, first try to
understand the cause before you attempt to fix it. You can even ask online, or compare
yourself with other readers of this book.

618
Playing with friends
Playing with friends
So, now you have created a working game; maybe you even put in some effort to create
an amazing map (better than the one we created for Project 2)—now you want to play it
with your friends.

619
Connecting to a listen server
Connecting to a listen server
This section will point you in the right direction, and it will allow you play with a friend.
But I will leave you with an exercise to create a nice UI to trigger this code.
Remember that we are in a listen server context.
For the Server, you can use this command to open a map as a listen server (but you
cannot use it to travel, which we are unfortunately not covering in this book); it's
basically an Open Level node, but we pass listen as an option:

Of course, substitute LevelName with the Actual name of the level.


For the Client, in order to connect to the server, it needs to Execute this Console
Command:

620
Connecting to a listen server

Of course, you need to substitute IP ADDRESS with the IP address of the server. In case
you are playing over the internet (and not in LAN), you might need to do port-forwarding
on your router, which is not covered in this book.

621
What have we missed?
What have we missed?
I know that you want to know more, but unluckily we now have come to the end of this
book, and I need to forward you to some more specific book for Multiplayer Games. If
we look at the list below of all of these things that we have learned about Multiplayer
Games that we didn't cover, it is never-ending:
Server travel
Game state
Player state
Sessions
Online subsystems
Dedicated servers
Network security
Actor relevancy and priority
Actor role
Etc...

I gave you this list, so you can search for them if you are curious to learn more.

622
Ideas for additional features
Ideas for additional features
The rest of this chapter will give you some directions on how to extend and add
additional features to our game. However, keep in mind that most are left as an exercise.

623
Pause!
Pause!
I think we can agree that 99.9% of games have a pause menu or at least a menu of some
kind. Pause menus can serve a range of different purposes. For example, they can not
only pause a game during gameplay, but they can also provide an array of different
options that a player can toggle on/off. In most cases, they also provide options for
players to save/load, restart, and even quit a game if they have had enough. In this
section, we’re going to learn how to create a simple pause menu that we will add
additional functionality to throughout the rest of this chapter.
Keep in mind that a Pause Menu is very rare in Multiplayer Games (or a pause menu that
actually stops the game). So be careful with the design. In some games, you can allow
only the Host of the game to Pause the game; even though you might have the problem to
overuse this. In our case, in a cooperative game, it’s a bit less of a problem, but still
present. Other games, such as Warcraft III, allow you to pause a limited number of times
during a game to prevent abuse.

624
Creating the Widget
Creating the Widget
As we have seen before when it comes to creating UIs in Chapter 4, creating a Pause
Menu requires pretty much the same process. To create the Pause Menu, we need to add
a few things from the Palette menu, as pictured here:

1. Create a background by using Image. You can either set an image or change the color of the tint. In our
case, we will just change the color of the tint.
2. Use Text to create a menu title. In our case, we will call it Game Paused.
3. Add a Button to resume the game. At this point, you can add the following buttons: Save, Load, Restart,
and Quit, since we will be adding functionality for these soon.
4. For each button, add some Text to indicate what the button is for.

5. Reposition your buttons so that they fit nicely within the screen window. Once you have created all the
buttons, you should have something that looks like the following:

625
Creating the Widget

For now, that is all that we need to do for the Pause Menu.

626
Creating the Blueprint for the Pause Menu
Creating the Blueprint for the Pause Menu
Now that we have created our Pause Menu Widget, we need to make it work. It is a very
straightforward process and, depending on how you want it to appear in-game, this
process will vary (maybe it appears in 3D physical space – it depends of the kind of game
you are developing). We will create a simple, ordinary Pause Menu that will appear on
the screen as if it were attached a 2D plane, which is triggered when the player presses
the “P” key.
To do this, we need to perform the following steps:
1. Create a Blueprint of the Actor type and call it BP_PauseMenu.
2. Within the Event Graph of BP_PauseMenu, type and select the P key (Input | Keyboard Events | P).
3. In the Details Panel of the P node, enable Execute when Paused:

4. Add search and add Flip/Flop.


5. Dragging from the A execution pin, type and select Create Widget.
6. Select the Widget Class like in the following image:

627
Creating the Blueprint for the Pause Menu

7. Select Add to Viewport.


8. Set Game Paused and enable it by checking the Paused checkbox.

9. Drag from the Return Value Pin of Create Pause Menu Widget Widget and type and select Remove from
Parent.
10. Connect the execution pin of Remove from Parent and type and sect Set Game Paused but do not
enable it.
11. Connect the B execution pin of the Flip/Flop node to the input pin of Remove from Parent.

Once you have finished, your Blueprint should look like the following image:

628
Creating the Blueprint for the Pause Menu

Now, you can continue on your own.

629
Save and load system (save point)
Save and load system (save point)
Here is another idea: unlike what we have done within our menu, what if you provided an
option for a player to save/load the game within the game environment itself. This means
that there is a location/asset within the game world that the player can locate, and here
they can access a menu to save/load their game. This option is great if you want to
control when a player can save/load a game during gameplay, and therefore remove the
possibility to do so via a menu that they can access at any point.
Keep in mind that in a Multiplayer Game this option is suitable for Co-Op campaign or
games (such as A Way Out).

630
&#xA0;Loading screens
Loading screens
Nobody likes to wait. It is tedious, annoying, and frustrating if it is for a long time. What
a lot of games do nowadays is try to create an experience as part of the loading screen.
For example, Assassin’s Creed used to allow you to control a character in an endless
environment, whereas now they have a bunch of tips that you can cycle through that
contain information about either gameplay or historical facts about the time period that
you are playing in.
Trying to create a Loading screen that works in multiplayer is tricky, but very important.
Some games create a kind of lobby level in which the player can select some options
while waiting for other players or for the new level to load.

631
Creating a checkpoint
Creating a checkpoint
You can allow the player to enable checkpoint-saves and restart the game from a
designated point in game-play. Checkpoints are useful things that can be automatically or
manually triggered by the player by that require that they approach and activate a
checkpoint. While checkpoints aren’t necessarily save points, they can serve as a marker
that allows a player to return back to a relatively close location in case they die, rather
than them having to complete the level again.
In the context of the Co-Op multiplayer we have created, a check point might be useful
when both players get killed by the Hounds.

632
Automatic checkpoints
Automatic checkpoints
Automatic checkpoints make life easier if players are engaging in fast-paced gameplay,
such as traveling through environments quickly or precariously. Imagine traversing a
large crevice only to misalign a jump and it for all to go downhill (literally). By
implementing automatic checkpoints, all a player has to do is to enter the zone of the
checkpoint and it will be triggered. So, unlike manual (player-triggered) checkpoints, the
player doesn't have to do anything for them to be activated.
This can work also on MMO (Massive Multiplayer Online) worlds; when a player dies,
they can spawn next to a checkpoint.

633
Manual (player-triggered) checkpoints
Manual (player-triggered) checkpoints
A manual checkpoint is pretty much the same as an automatic one except it requires a
player to execute it. It may be something as simple as them walking over a pressure plate
on the ground or pressing an interaction key to activate it. Depending on your gameplay
style, it will change your choice for which one is more appropriate.
For the manual checkpoints, we’ll have the player spawn in one of three places
(depending on whether they are activated). You can see these three places numbered in
the following screenshot:

The idea here is that we need the player to walk over these checkpoints in order to
activate them.
These kind of Checkpoints are useful for Death-match Multiplayer games, so that the
Player can quickly decide where they want to re-spawn. In some games, the Player can
choose on which checkpoint to re-spawn.

634
&#xA0;Creating an option to restart (and Quit)
Creating an option to restart (and Quit)
Sometimes, you don't have enough health to compete against a boss right after a save
point, which can be annoying. So sometimes, you need to restart a level in order to gain
more health and stock up on supplies.
Before we can allow the player to restart, we first need to add these buttons
(Restart/Quit) to the menu. Like we have done for the save/load buttons, add an
additional button to the Pause Menu widget to allow the player to restart.
This might be useful when a set of players enters a dungeon together and would like to
restart the level. Of course, you have many design choices here. Who is going to decide
to restart the game? The Host? Up to a Vote?
The same thing goes for a Quit option. What happens if a Player quits? And if it is the
Host?
Moreover, once a player clicks the Quit button, we want to make sure that they actually
want to quit; we want to present them with a confirmation screen that asks them yes or
no.

635
Expanding upon what you've learned here
Expanding upon what you've learned here
There isn’t a great deal of things that you can do with a Pause Menu in terms of
functionality since most of the options can be toggled on/off, selected, or chosen via a
slider. However, what sets one menu apart from the others is its aesthetics. Therefore, to
extend what you have learned in this chapter, I encourage you to consider how you could
change and improve the aesthetics of what you have been inspired to do here:
Customize the Pause Menu by adding a different background or even by creating your own buttons to
personalize the design.
Using similar logic to the quit confirmation screen, create a way to asks the player whether they want to
overwrite a save file.
Try to think of other ways that you can make a player activate a checkpoint.

Also, try to fix other bugs, if there are any in your game.
Another great thing to do is to give some kind of the main menu to the game in which you
can either create a new game/server, and another to join a server by insert the IP Address
in a specific UI.

636
Summary
Summary
In this chapter, we cleaned up the last few bugs in our game so now it is finally READY!
We learned the difference between the dedicated and listen server. We explored how we
can play with our friends by using specific Blueprints node, and I encourage you to
experiment with them (first in LAN, so you don't have to deal with Port Forwarding).
The rest of the chapter was just some inspirational material to help motivate you to
challenge yourself and to apply what you have learned in different ways. We created a
Pause Menu, and a save and load system, along with options to restart and quit. We
created a loading screen, and implemented checkpoints within our game.
I think it is safe to say that we have covered quite a lot of what we need to get core
features implemented within a game. Next, in our final chapter, we’ll cover the last few
tidbits to complete the game design journey and to continue extending the knowledge that
you have accumulated so far. We will look at some quick tips on how to optimize your
game as well as loading times. We will look at how to get your game ready to distribute
by covering various package settings. Let's begin our final goodbyes and head over to our
last location.

637
Building and Publishing
Building and Publishing
We have finally reached the end of building our game. You should have a pretty solid
understanding of what it takes to great a range of different types of games and
experiences within Unreal. But now, we must conclude it all with building, publishing,
and providing a way for people to access your game/interactive experience.
In this chapter, we'll cover the following topics:
Quick tips on how to optimize your game
How to optimize loading times
Getting ready to distribute your game
Package settings
Expanding upon what you've learned here

638
Optimizing the game
Optimizing the game
Let's begin by optimizing our game. There are several ways that we can optimize our
game, depending on our needs. In saying this, ideally, you should not be thinking about
optimizing at the end of designing your game. This is something you should be
considering throughout every process, especially when it comes to the specifications of
your target device. However, once you have arrived at the end, there is some tweaking
we can do to improve the game's performance. Of course, I cannot stress the importance
of doing this both at the beginning and during your game's development rather than at the
end! Of course, optimization is such a broader topic that would require a book on its own
to be properly explained; but here are some tips and tricks that you can follow to improve
the overall performance of many different areas of your game to improve its
performance.

639
Optimizing loading times
Optimizing loading times
It is essential to have short loading times regardless of the type of game, because the
moment a player has to wait can be the difference between them enjoying your game or
getting tired of it. UE4 provides us with several ways to optimize the loading time of a
project while we are packaging it. To begin, navigate to your project settings, and under
the Engine section on the left, you will find a subsection named Streaming. Once
selected, you can edit the streaming properties. In particular, we can enable the two
options highlighted in the following screenshot:

640
Optimizing loading times
These two options can help you in cutting the loading time for your game. Let's explore
what they do:
The Event-Driven Loader (EDL): As you can see in the screenshot, this is enabled by default.
Usually, the EDL is able to cut the load time in half, and it is a stable feature of the engine. In some rare
situations, you might want to turn this off, for instance for incompatibility with a specific code, and
that's the reason why you have the possibility to turn it off.

Do not confuse EDL with the Edit Decision Lists (EDL), which are some files that carry
information on cinematic cuts (used by Sequencer within Unreal, they can also be
exported from the engine for importing cinematic shoots in other video-editing programs).
The Asynchronous Loading Thread (ALT): as you can see from the screenshot, it is disabled by
default. However, but it can be enabled. Both types of games that have up-front loading, as well as
games that stream data continuously can all benefit from using ALT. In fact, it allows us to load in
parallel "post-loading code" and "serialization" (using two different threads), which results in a faster
(even double) loading speed.

This function is not activated by default because loading on two separate threads requires
that all the code in UObject class constructors, PostInitProperties functions, and
serialization functions is thread-safe! If you don't know what all of these things are, don't
worry. In fact, they are mainly related to C++. Thus, in Blueprint-only projects, you
should be able to turn on this option without too many problems, and get a time much
loading faster!

641
Optimizing your game
Optimizing your game
When it comes to optimizing assets, I could write another book. Moreover, it is something
you should start doing way before the end of your production. In any case, here are some
quick tips on how you can start thinking about optimization (even if you are the very end
of your design):
Checking resource use: This can be a great start to seeing whether your project contains issues that are
likely to impact your game's functioning. In Chapter 12, Game Analytics, Debugging, and Functional
Testing, we saw the profiler, which is a great place where to start looking for resource usage.
Poly crunching: You can optimize your assets by reducing the number of polygons that an asset has.
This will only be possible for static meshes, as skeletal meshes will require that you reduce the number
of polygons within other programs (for example, Maya, 3DS Max, and Blender).
Instancing: When you have many meshes of the same type, consider merging them, or use instances.
Reducing texture size : If textures are too big, you can reduce them, and try to balance quality versus
performance.
Checking LODs: This checks whether you are using Level of Details (LODs) on your static meshes.
Disabling Unused Plugins: If a plugin in your project is activated, but you are not using it, removing it
will guarantee that it will not be included in the packaged version of your game.

I gave you this list so that you have a starting point on where to start searching about
optimization in case you are interested in extending further.

642
Packaging and publishing&#xA0;
Packaging and publishing
Now that our game has been optimized, it's time to create an executable. Simply put, an
executable is a packaged version of your game that contains only your game. With
everything ready to go, we must properly package our game, which ensures that all of the
code that we have created as well as the content is up to date and in the proper format for
the platform that we are targeting. In saying that, it is not an Unreal Engine file, therefore
it is not modifiable, but rather it is the game. Copy it to a USB, HDD, upload it to the
Google Play Store, or even burn it to a disk. At this point, you have a transportable
version of your game.
Before we start doing anything, there are several steps that we need to perform in Unreal
during the packaging process. To begin, it is important to know that the Project-specific
source code will be compiled first. This means that the code that is only part of our
project will be compiled first (anything that is within the UE4 project files that aren’t part
of our game is excluded). Next, once the code has been compiled, all required content
(assets, audio files, and so on) will be converted, or rather cooked, in a way so that the
target platform can understand it. Another way to think about this is that during this
stage, the content is translated in Android, iOS, Windows, and so on. Once everything
has been compiled and cooked, it will be bundled into a "distributable" set of files, such
as an installer/executable. This means that the game is ready to go once someone tries to
run/launch it on their computer (or phone or tablet).
With this said, let's package our game (this same process applies for anything that you
want to export out of UE4 and onto a target platform).

643
Getting Your Game Ready
Getting Your Game Ready
Before jump into the packaging process, there are a couple of things you should do to
ensure the best results for your players.
First of all, be sure to change the Lighting settings to Production. This will make the
lighting build much longer (and this is the reason why you didn't use these setting before,
but only during the last phase of your game, just before to be published), but it guarantees
the best results. You can change the setting from the menu on top of the viewport, by
navigating from the build icon (Build | Lighting Quality | Production):

Once you set this, be sure to open every map and rebuild everything (not only the
lighting), so you can just press the Build button to build everything from the lights to the
geometry.
Then, you should definitively playtest your game, check that all the gameplay works as
expected, and tweak if necessary (remember that if you change the level, you will need
to build the level again). And now, we are ready!

644
Packaging Settings
Packaging Settings
Before packaging your game, you will first need to tweak some of the settings related to
the packaging process.
First of all, it is important to set a Game Default Map. This will be the map that will load
when your (packaged) game begins. However, if you do not set a Game Default Map,
and are using a blank project, when you run your packaged game, you will only see a
black screen. To set your Game Default Map, you will need to head to Edit | Project
Settings | Maps & Modes under the Project tab:

645
Packaging Settings

Coming to the actual packaging settings, navigate to Edit | Project


Settings | Packaging under the Project tab:

646
Packaging Settings

As you can see, there are many settings, and these are just the main ones. In fact, the
packaging process might involve many steps, but for our learning purposes, if we learn
the settings in this menu, it will be more than enough for now. Let's break them down into
sections, and explore which are their effect in the packaging process, at least the main
ones:

647
Packaging Settings

The settings displayed in the preceding image are general to the whole project, and in
particular, they change how the overall packaging process takes place:
Build: Specifies when to create the game executable for your game.
Build Configuration: Determines on which configuration you would like to build. For instance, you
might want to keep the console enabled while exporting your game, debug tools, and so on. You can
keep those during the packaging process by selecting the right configuration. Usually, for Blueprint-only
projects, this is not a big deal, but you may still want to use your console by using the
Development configuration. Before distributing your game, be sure to change this configuration into
Shipping.
Staging Directory: This is where your game will be packaged by default.
648
Packaging Settings
Full Rebuild: If checked, Unreal will perform a Full Rebuild, which means that it will start the
packaging process from scratch every time. It is useful to keep this disabled during development so that
Unreal packages only the differences from the previous version of your packaged project. However,
enabling it just before building a Full Rebuild is strongly suggested.
For Distribuition: If checked, it will create a distribute build with the Shipping configuration. This is
needed when you want to distribute in the App store.
Include Debug Files: As the name suggests, if checked, debug files will be cooked in the packaged
version of your game. This option allows you to perform debug operations in your cooked game, but it
should be removed before you ship your game:

649
Packaging Settings

The settings in the preceding screenshot, instead, identify more specific options that
should be considered when preparing the project before packaging. For now, we are just
going through the main ones:
Use Pak File : When checked (it is by default), all your game content will be inside a .pak file.
Generate Chunks: If checked, it will generate different chunks. Some platforms allow you to stream a
different chunk at a different time. Once selected, you will be able to decide which asset goes in which
chunk.
Generate No Chunks: If checked, it forces to not use chunks regardless of the platform-specific
settings.
Share Material Shader Code : If true, it allows you to share code among different materials, resulting
650
Packaging Settings
in a smaller (file size) packaged game, but loading time might increase.
Shared Material Native Libraries: If the target platform has a specific material library, if this option
is checked, Unreal will try to use the native library to share code among materials. Once again, this will
result in a smaller packaged game size, but long loading times.
Blueprint Nativization: If enabled, all of your blueprints (or a subset, depending on which settings you
are selecting) will be converted into C++ code for you before packaging, without the need for you to
know how to code in C++. This will make the performance of your game much faster, which is very
useful for a platform with limited capabilities. However, the downside is that the size of your packaged
game will grow due to extra data that needs to be stored to support the nativization (and that's why you
can select the blueprints you want to nativize, usually the slowest ones).

You can read more about Blueprint Nativization here: https://docs.unrealengine.com/en-


US/Engine/Blueprints/TechnicalGuide/NativizingBlueprints.
Include prerequisites installer: If enabled (by default it is), your packaged game will have the installer
to the prerequisite. In fact, your game needs a series of libraries to run, which need to be installed on
your computer. By enabling this option, your game will contain the installers of these libraries, so it can
be successfully installed/run on any computer.

These are the main settings we can give to our packaging process.
To learn more about the other settings, just hover your mouse, and you'll get a short
description. Also, don't forget to expand the two little arrows at the bottom to see more
settings to explore.

651
Packaging
Packaging
The next phase consists of creating the packaged version of our game. Of course, this will
vary depending on which platform you are going to package, but the single steps of the
process are always the same:
1. Navigate to the Editors main menu and click on File | Package Project | [PlatformName]:

652
Packaging

2. You will be presented with a dialog to select the target directory. If packaging completes successfully,
653
Packaging
this directory will then contain the packaged project:

3. Here you will need to confirm the location of the target directory. It is important to note here that
bBecause packaging can be an extremely time-consuming process, it is therefore executed in the
background. In this way, you still have the ability to use the Editor while you are waiting for the
packaging process to complete. Keep in mind though that any changes that you make at this point will
not be included in the packaged project. You will need to run the packaging process again to include
them. While your project is packaging, a status indicator will be displayed in the bottom-right corner of
the Editor to indicate the progress, like in the image below:

It is important to note here that the status indicator provides a Cancel button, which can
be used to stop the packaging process at any point. If you click the Cancel button, you
654
Packaging
will see the following notification:

In addition, the Show Output Log link can be used to view more detailed information of
the packaging process such as errors or warnings. The information within these logs can
be quite useful if for some reason your project fails to package, or for catching warnings
that could reveal potential bugs in the product.Once the packaging process completes, we
have an executable of our game, which we can share with friends for testing (even if your
friend doesn't have Unreal Installed). Potentially that file is the one you will use to
distribute across the world and online stores.

655
Distribution on Online Stores
Distribution on Online Stores
When Dealing with mobile stores (and online stores in general), your game will have a
series of additional requirements. For instance, for the App Store (iOS games) or Google
Play Store (Android games), you will need to package your game in Distribution mode,
which you can set in the Packaging settings we saw earlier in this chapter.
If you're developing for iOS, you will need to create a Distribution certificate and
MobileProvision directly from the Apple developer website, and name your distribution
with the Distro_ prefix.
On Android, you will have to create a key that you will use to sign the .apk file you
created in the packaging process. To change the settings of the signing, you can navigate
into the settings by going to Edit | Project Settings | Android. Here, you will find many
options to configure your Android game. Under the Distribution section, you will find all
the options you need to tweak and create a key for signing your game.
Stores can be difficult to deal with, but they are essential for the success of your game, so
be sure to learn what you need to do to get your game accepted by a particular store.
If you need to access some advanced setting while you're preparing a package for
distribution, you can access these settings by doing the following: Clicking File | Package
Project | Packaging Settings.... Alternatively, Edit | Project Settings | Packaging
Here, within the main menu, you will find more advanced configuration and packaging
options for your project.

656
Expanding upon what you&#x2019;ve learned here
Expanding upon what you’ve learned here
Usually, in this section, I would give you a nice list of challenges that encourage you to
push the boundaries of your knowledge and skills in each chapter. However, now that we
are at the end, it is time for you to identify a direction that you want to head toward as a
game developer and begin to refine your knowledge in that way. So, based on what you
know now and what interests you, I encourage you to extend what you’ve learned here
by pushing yourself toward new challenges and more specific areas of development. A
jack-of-all-trades is good, but we do not have enough lifetimes to learn everything!
Therefore, the important thing now is not to stop; do not lose your momentum. From
here, try to expand upon what you have learned. Try to make more complicated materials
or advanced gameplay. Let's look at some suggestions about where to start.

657
Reading books and watching tutorials
Reading books and watching tutorials
The internet provides us with the ability to learn anything at any point in time and
anywhere. So, why not take advantage of it? There are thousands of tutorials online that
you watch or read; some of them are free and some are paid, but they are all ways to
extend your skills. In some cases, especially when different versions of the engine are
available, you can learn a thing or two by watching tutorials about things that you already
know. The important thing is to never assume that you know everything, because while it
may be true at that point in time, technology, plugins, and settings are constantly evolving
and so should you!
Packt Publishing has a lot of other interesting reads that cover various topics related to
developing in Unreal, so make sure to check them out by searching their official site:
https://www.packtpub.com/.
For instance, if you want to learn more about Artificial Intelligence in Unreal, I suggest
you "Hands-On Game AI Programming in Unreal Engine 4" by Francesco Sapio. The
book is not out yet at the moment of writing, but hopefully it soon will be; so be sure to
check it out!
Another great read is Sam's Teach Yourself Unreal Engine 4 Game Development in 24
hours. Both its structure and content provide a great path for starting out and it covers
other general areas that are essential to developing your skills with Unreal. You can find
the book on Amazon (among other book retailers!): https://www.amazon.com/Unreal-
Engine-Development-Hours-Yourself-ebook/dp/B01GCZFLEQ.
Be sure to check out the following sites for a wide range of tutorials and courses that can
help you on your way to becoming an expert with Unreal:
Coursera: https://www.coursera.org
Pluralsight: https://www.pluralsight.com
Udemy: https://www.udemy.com/

Finally, here is an example of a great online course to get you started in Unreal:
Unreal Engine 4: How to Develop Your First Two Games by Chris
Murphy (https://www.udemy.com/unreale4/):

658
Reading books and watching tutorials

659
Twitch Live streams
Twitch Live streams
A lot of people like to show what they do when they are creating things in Unreal and
many people utilize the Twitch platform to do so. Generally speaking, Twitch allows
users to stream live content, encourages interaction among viewers while they are
streaming, and offers a raw and authentic view into what it is like to develop in real-time:

660
UE4 Game Jams
UE4 Game Jams
One of the most awesome things that Epic Games organizes throughout the year (besides
great events) is their game jams. You can be literally anywhere in the entire world (as
well as your team members!) and participate.
Of course, each game jam has their own requirements, so be sure to check those before
starting, but they are a great way to put everything that you learn into practice, with the
chance to be a part of something bigger (and also win things!):

661
UE4 Game Jams

662
Meet-ups
Meet-ups
Just like the game jams, Unreal has a bunch of meet-ups that are located around the
world. The point of these meet-ups is to bring everyone together who is interested in
developing things in Unreal (regardless of their level of experience) and create a
community of shared knowledge and a platform where you can share ideas and projects
that you are working on. Therefore, make sure that you check out the Unreal meet-ups
and join those closest to you:

663
Meet-ups

664
Forums and online networking
Forums and online networking
This goes without saying, but for a community that is based in a digital realm, online
forums and networking are full of opportunities that you can explore when looking for
help or a way to help others. Even if you think that your question is stupid, there are
probably another 20 people who want an answer but are too afraid to ask:

665
Forums and online networking

666
Most important of all, keep making games!
Most important of all, keep making games!
Challenge yourself, make games in different genres, change the way the mechanics work.
Instead of creating a military-style shooter, create something that shoots flowers and
promotes peace. It is a bit cliché I know, but challenge yourself by changing one or
several elements of a game’s design. You may even find yourself creating a new game
altogether.
I will conclude this book with a final thought: when you really think about it, the
difference between being a game designer and not being one is simply making games.

667
Summary
Summary
Well, that's it. It's Game Over for this book. However, it is in no way game over for what
you have learned. By now (if you have followed the book sequentially from the start),
you will have developed your skills as a game designer and picked up a few tricks along
the way. In addition, you should be used to how Blueprints work and how they are
essential in any game developer's toolkit, especially for those who do not come from a
programming background. Blueprints gives you the power to create those abstract
concepts and exciting adventures in your (and your team's) mind. So, go create your own
adventures now using the skills that you have gained here! Happy game developing!

668
Other Books You May Enjoy
Other Books You May Enjoy
If you enjoyed this book, you may be interested in these other books by Packt:

Learning C++ by Building Games with Unreal Engine 4 - Second Edition


Sharan Volin
ISBN: 9781788476249

Learn the basics of C++ and also basic UE4 editing


Learn your way around the UE4 editor and the basics of using C++ and Blueprints within the engine
Learn how to use basic C++ containers and data structures to store your game data
Create players, NPCs, and monsters
Give information to users using the UE4 UMG UI system
Gain a basic understanding of how to use procedural programming to give your game more replay value
Learn how UE4 can help you build projects using the hottest new technologies, such as VR and AR

669
Other Books You May Enjoy
Mastering Game Development with Unreal Engine 4 - Second Edition
Matt Edmonds
ISBN: 9781788991445

The fundamentals of a combat-based game that will let you build and work all other systems from the
core gameplay: the input, inventory, A.I. enemies, U.I., and audio
Manage performance tools and branching shaders based on platform capabilities in the Material Editor
Explore scene or level transitions and management strategies
Improve visuals using UE4 systems such as Volumetric Lightmaps, Precomputed Lighting, and
Cutscenes
Implement audio-to-animation timelines and trigger them from visual FX
Integrate Augmented Reality into a game with UE4's brand new ARKit and ARCore support
Perform almost any game logic needed via Blueprint Visual Scripting, and know when to implement it
in Blueprint as opposed to C++

670
Leave a review - let other readers know what you think
Leave a review - let other readers know what you think
Please share your thoughts on this book with others by leaving a review on the site that
you bought it from. If you purchased the book from Amazon, please leave us an honest
review on this book's Amazon page. This is vital so that other potential readers can see
and use your unbiased opinion to make purchasing decisions, we can understand what
our customers think about our products, and our authors can see your feedback on the
title that they have worked with Packt to create. It will only take a few minutes of your
time, but is valuable to other potential customers, our authors, and Packt. Thank you!

671

You might also like