As Unreal Engine continually evolves, we often release ‘Experimental’ and ‘Early Access’ features for developers to explore. As these names imply, these features are not yet production ready, but provide an opportunity to experience – and contribute to…
When working with game UI, the typical UMG Text block offers a healthy variety of style options and customizations. However, many developers have found the need for more flexible text that supports markup for things like style changes, inline images, hyperlinks, and much more. Much of this has already been possible with the experimental Rich Text Block widget through code.
For the 4.20 release, the widget was made available to UMG and in the process it’s workflow polished to be more flexible and extensible than before. As part of this polishing phase, rather than attempt to support every possible customization a developer may need, we’ve set the Rich Text Block up to accept Decorator classes, enabling you to define the markup behavior you need for your project. You’ll find that a single Decorator class has been provided as an example for setting up your own decorators with RichTextBlockImageDecorator.cpp.
In this blog post, I’ll go over both how to work with the new Rich Text Block widget in UMG as a UI designer and as a programmer. I’ll explain how you can extend it with additional functionality using Decorator classes. Before diving right into adding your own customizations, it may be helpful to familiarize yourself with the newly exposed Rich Text Block functionality in UMG. The Rich Text Block widget enables you to customize the contents of your block using text styles and decorators using Data Table Assets or your own Decorator classes.
The Data Table Asset you create is used to store any type of data based on any user-defined struct. When you create a Data Table, you’ll notice there are two provided: Text Style Row and Image Row. Text Style Row structs are part of the built-in stylings provided with Rich Text Block that enables you to define the font type, whether it is outlined, what type of color and size it should be, and much more. The Image Row is part of the provided RichTextBlockImageDecorator example class that enables you to specify any Decorator classes in the Rich Text Block widget. With it, like the Text Style Row struct, you’ll be able to define properties for in-line images such as size scaling, tint, alignment, and more.
The RichTextBlockImageDecorator class example provides you with a starting point to create your own markup text that can be replaced with whatever Slate content you want, including things such as images, hyperlinks, and even entire widgets! Data Tables can hold any type of data and be set up in the Editor through a Data Table Asset.
First of all, we’ll need to create a new Widget Blueprint and use the Palette to drag a Rich Text Block onto the Canvas. With the Rich Text Block selected, use the Details panel to locate the Text Styles Set. This asset assignment slot lets us pass in a data table of styles that defines both our Text Style and any number of additional styles we may wish to use. You can go ahead and create a new Data Table by selecting this assignment dropdown and selecting Data Table or by using the Content Browser and selecting Add New > Miscellaneous > Data Table.
When you create a Data Table, you can go ahead and create it right from inside the Details panel in UMG. Choose Rich Text Style Row for the row struct from the Pick Structure window and dropdown.
Open up your new Data Table by double-clicking it in the Details panel in UMG or from the Content Browser. In the Data Table Editor, we’ll start by creating a new row name “Default.” This row represents our text in its default state and will automatically be used by the Rich Text Block for any text where it’s not been explicitly set to a different style.
Explore the different options under your newly created Default row and set the baseline style you want for the type of font, size, typeface, and more. Once you’re happy with that, go ahead and add some additional styles by clicking the plus (+) button to add a new row and then enter a name in the Row Name text box.
Back in the Widget Blueprint with your Data Table asset assigned, go ahead and add some text to the Text section of the Rich Text Block through the Details panel.
In the UMG toolbar, you may need to click the Compile button to display text in the Rich Text Block widget.
The text here is using the Default row we set up. To apply another one of your styles created in your Data Table Asset, use the following format to apply style to the wrapped text:
In this example, we wrapped the text we want to inherit the style in our tag that is used in our Data Table Asset for this row using Rich. In doing so, the text now inherits the properties we set, in this case, orange text with a black outline.
Keep in mind that this style tag does not require any prefix or postfix, such as RichText.* to work, and it is not case-sensitive.
At this point, we’re now able to apply different styles to text within the Rich Text Block but what if we wanted to inject something other text? We can use Decorators to do that by setting up our own markup tags. These markup tags let us use Slate to render anything we want seamlessly within our text.
To get you started, we’ve included an example RichTextBlockImageDecorator class that can be used to add an image to a Rich Text Block using a Decorator class. Like the built-in stylings of the Rich Text Style Row, the Rich Image Row struct defines all the images we would want to support with in line text.
Now, we’ll continue by extending the provided RichTextBlockImageDecorator class so that we can point our subclass at the Rich Image Row Data Table that we just created. The simplest way to do this is to create a new Blueprint class, choose the RichTextBlockImageDecorator class that is provided as the parent class, open the Blueprint and assign the Data Table to the Image Set property of the class.
Take note that in 4.20, the image decorator doesn’t appear in the list of parent classes, however, this will be supported in 4.21. For the time being, you can extend it as a C++ class and either assign your data table in the C++ file or add Blueprintable to the UCLASS macro at the top of the header in order to extend your subclass as a Blueprint.
Once your Decorator is set up, add it to your Rich Text Block’s Decorator Classes array and insert images from your table using the following markup:
You may need to hit the Compile button in the toolbar for the changes to display and take effect.
Adding New Decorators
While we do provide the RichTextBlockImageDecorator class as an example, the best part about the Rich Text Block is that you can now define your own custom decorators that leverage the full power of Slate, enabling you to add anything you want in line with your your text. To do this, you’ll need to write two classes: a URichTextBlockDecorator and an FRichTextDecorator. Once these classes are set up, you’ll be able to add your decorator to any Rich Text Block via the DecoratorClasses array in the Rich Text Block widget in UMG. You’ll also be able to use your markup to parse text with your decorators.
URichTextBlockDecorator defines an UObject class that can expose properties to the Editor’s Details panel. At a bare minimum, you’ll need to implement CreateDecorator, which should return a SharedPtr to the FRichTextDecorator instance you’ll create to do all your heavy lifting. You’re welcome to also implement any properties and utility functions here, which will let your designers create subclasses of your Decorator as a Blueprint in order to pass in whatever data they need. You might recall that the RichTextBlockImageDecorator defines a data table property so that we can pass in our table of images. Anything you want to be modified in Blueprint should exist here on the UObject.
FRichTextDecorator is responsible for the actual parsing/substitution of markup tags and requires two functions to be implemented. The first function, Supports, is given the contents of the markup tag via an FTextRunParseResults and simply returns true or false depending on whether the decorator is actually responsible for handling of this tag. Supports will be called for every decorator in your DecoratorClasses array before falling back to just displaying the tag as regular text if we can’t find the decorator to handle it. The second function, CreateDecoratorWidget, is called to actually construct and return the widget by replacing the supported markup tag. You’ll have access to FTextRunInfo if you need any text or metadata in the tag.
In the case of the RichTextBlockImageDecorator class, we define an SRichInlineImage widget and populate it with the correct image from our data table that is passed to the UObject wrapper class before passing it as the return value for the CreatorDecoratorWidget.
Using Rich Text in Your Project
We’ve gone over how to use the Rich Text Block’s built-in features and how to write Decorator classes to add your own functionality. Now, how does this fit into your project’s workflow?
If you find yourself setting up the Decorator Classes array with the same set of decorators every time you make a Rich Text Block, it can be useful to your own subclass of the Rich Text widget with a default set of decorators. If you need even more control, you’ll also notice that SRich Text Block has support for custom parsers and marshallers. You can write your own parsers to change the rules on how markup tags are detected and processed, and a custom marshaller will give you control over how your text is laid out within the widget.
While it may be tempting to start using Rich Text Blocks widgets in place of all your project’s text areas, there is a performance cost associated with parsing the text in search of tags. For anything where performance may be a concern, you’ll want to continue to use regular text blocks wherever the extra features of the Rich Text Block are not needed.
The Rich Text Block widget opens up a plethora of possibilities for applying interesting effects to your project’s text. With it, you’ll be able to apply simple effects like text highlighting and gamepad buttons or more interactive effects like inline buttons and loot links, with decorators letting you add in anything you can imagine!
Visit our documentation for Rich Text Block to dive in and get started using it!
Back in March, Epic Games released over $12 million worth of Paragon assets for free and over the past several months we have run a series of animation livestreams covering methods you can use to get the Paragon animations working on a character in you…
When designing the architecture for an Unreal Engine 4 game, one of the primary questions you’ll have to answer is whether gameplay logic and data should be implemented in Blueprints, C++, or both. There is no single answer to this question, as it vari…
While summer vacation welcomes a relaxing break from the rigors of teaching, this is also the perfect time for educators to add valuable Epic-approved content to their lectures. With Unreal Engine developers in such high demand throughout the world, more and more academic institutions are looking to bring UE4 into their classrooms. Whether it comes to learning the fundamentals of game development, developing virtual reality games, apps, and movies, or learning Blueprints, Epic has got you covered! Introducing our official Unreal Engine Instructors’ Guides – free to use for all educators.
Teach Your Students How to Use Unreal Engine 4
The Unreal Engine 4 Instructors’ guides were designed for a seamless transition from textbook to lecture as they cover the same tools used by professional developers to ship successful games. Instructors can now access these professionally-authored courses to add to their current teaching materials, all for free! These courses includes lectures, quizzes, and tests. You can start teaching Unreal Engine 4 this coming academic term with these fully-featured Instructors’ Guides.
What’s Inside the Guides?
These guides include:
• Exercises to promote active learning and engagement
• Complete lectures and class notes in PowerPoint that can be added into your own lectures
• Ready to use Unreal Engine 4 game project files and example content
• Summative and formative assessments, premade weekly quizzes, midterm and final exams complete with answer keys
• Unreal Engine terminology section. A glossary for each unit that covers the need-to-know terminology and concepts to ensure lectures can be taught effectively
How Do I Use the Guides?
Incorporate Into Your Own Curriculum
While using the Unreal Engine 4 Instructors’ Guides, you are free to:
• Deploy directly into the classroom and/or incorporate into your own curriculum
• Share – copy and redistribute the material in any medium or format
• Adapt – remix, transform, and build upon the material
Unreal Engine 4 VR Cookbook – Available Now
This guide is based on the book Unreal Engine VR Cookbook: Developing Virtual Reality with UE4, by Mitch McCaffrey. Featuring 12 lectures, with accompanying quizzes, terminology sheets, and associated project files. Teach the fundamentals of VR development from an Unreal Engine-centric approach.
Game Development with Unreal Engine 4 – Available Now
Written by Epic Game’s Chris Murphy, this guide includes 12 detailed lectures, and complete teacher’s guide with notes, terminology and sample content. This guide will be very helpful for building your game-development courses.
Teach Yourself Unreal Engine 4 – Available Now
This guide is based on the book, Sams Teach Yourself Unreal Engine 4 Game Development in 24 Hours by Aram Cookson, Ryan DowlingSoka and Clinton Crumpler. The guide features 22 lectures with corresponding quizzes, tests, and content. This guide covers learning Unreal Engine’s fundamental features.
Unreal Engine 4 for Unity Users – Coming Soon
Unreal Engine 4 for Design and Visualization – Coming Soon
Unreal Engine 4 Blueprints Guide – Coming Soon
Visit the educator’s resource section of our site to download the available guides today!
Epic is happy to introduce the Unreal Engine Online Learning platform, the new home for all our training series and video tutorials on Unreal Engine. Our extensive online training illustrates common workflows in a series of detailed yet easy-to-follow …
In Unreal Engine 4.20, the new Proxy LOD tool, which was essential for shipping Fortnite on mobile, was introduced. The Proxy LOD tool provides massive performance advantages by reducing rendering cost due to poly count, draw calls, and material complexity. Proxy LOD also delivers significant gains when optimizing content for mobile and console platforms.
In this article, we’ll explore how the technical artists and engineers at Epic developed this ingenious solution that ensures that the construction and destruction elements found in Fortnite Battle Royale (FNBR) played and looked the same no matter what platform it was being played on.
Consistency is Key
Whether you’re destroying cars to harvest resources in order to build the fort of your dreams, or frantically building walls to avoid oncoming fire, the construction and destruction of objects is a crucial feature when playing FNBR.
When we were implementing crossplay, it was vital for Epic to make sure that every player had a fair chance to win matches, regardless of platform. To do this, the Fortnite team had to come up with a way to reduce the number of draw calls or the number of objects that are displayed on screen at one time to overcome any performance problems that might arise for two of the most important mechanics in FNBR, constructing and destroying objects.
Constructing a Modular World
To better understand the problems that are introduced with player-caused destruction, you first need to know how the buildings in FNBR are constructed. Each building you see in FNBR is built out of a series of modular pieces that can be quickly “snapped” together to make any structure that is needed. This modular approach to building also helps cut down on the number of unique assets that are required, saving precious resources like memory. This is because you can reuse the various modular pieces in different ways with different materials and textures to give your buildings an unlimited amount of variety without having to load additional objects into memory. You can see an example of the types of results that can be achieved when using modular construction in the image below.
The building that is on the left-hand side of the image (above) is constructed using only the nine Static Mesh Actors that you see on the right-hand side of the image, minus the various Trim and Props that live inside each building. Constructing the buildings in this manner also makes it incredibly easy to display the player-caused destruction because all that needs to be done to signify a piece has been destroyed is to disable both the rendering and collision of the destroyed piece. While this method of displaying destruction works well for both PC and consoles, it does present some issues on less powerful platforms, such as mobile devices. The reason for this is due to the sheer rendering cost of drawing the 350 to 400 individual pieces that make up the buildings in FNBR. In the following GIF, you can see just how many pieces make-up a typical building.
While this is not an issue for PC and consoles, it is an issue for platforms like smartphones where the entire scene needs to be composed of less than 1,000 pieces.
Now that we understand a little bit about how buildings are created as a whole, let’s take a look at how each component is built, as that also plays a role in how destruction is displayed. The following flowchart breaks down how the information in the rest of this document is laid out.
Less is More (Optimized)
Even with the modular type construction that is used in FNBR, you will eventually hit a hard limit on how many objects you can have on-screen at one time. This hard limit, referred to as Draw Calls, presents a big problem as each platform you can play FNBR on will have a different amount of draw calls that can be displayed at one time. To ensure that each platform that you can play FNBR on has a smooth and stable framerate, each Static Mesh that is used in FNBR contains multiple Level Of Detail (LOD) Static Meshes. LOD’s are a commonly used video game optimization technique that works by displaying a new lower triangle version of the Static Mesh when the Static Mesh is a certain distance away from the camera.
The above image shows one of the many modular wall Static Meshes that are used to make the various buildings you see in FNBR. When you are very close to the wall, you will see the Static Mesh that is on the far left-hand side of the image above. As the camera is moved further and further away from the wall, the different LOD’s will be displayed, like in the following GIF.
When this technique is applied to an entire building, you will get something that looks like the following image.
On the left-hand side of the above image, you can see what the original building looked like and on the right-hand side, you can see what the building looks like using only the last LOD. While the version of the building on the right-hand side is what we want, it is still made of far too many pieces to be rendered efficiently on some platforms. To address this issue and still be able to display player-caused destruction, we are going to need to employ some new tools and some “old school” Static Mesh production techniques.
Kicking it “Old School”
Before we take a further look at how player-caused destruction is displayed, we first need to take a look at the very last LOD that is used in each of the modular Static Meshes as it was created in a special way. Using the UE4 Static Mesh Editor to open up one of these modular building pieces and then forcing it to display the last LOD will give us something that looks like the following image:
While this looks like an average Static Mesh, make sure to take note that the Triangle count is 12 with the Vertex count being 18. While these numbers seem low, they are actually smaller than you can get when using a Digital Content Creation (DCC) to create a cube that is the exact same size and shape. In the following image, the same modular building piece was created in a DCC and then exported to UE4. The created Static Mesh is the exact same size and shape but notice that this Static Mesh has six extra vertices.
While having only six extra vertices does not sound like a lot, it can quickly add up. For example, if the above piece is used 30 times in a single building, it would add around 36 additional vertices to the building. Now take the 36 additional vertices and multiply that by 100 structures and you get 3,600 additional vertices that have to be rendered but are otherwise not used. To get rid of these extra vertices, these modular Static Meshes where adjusted in the following way:
- First, each modular piece that could support it was forced to not use any Smoothing Groups.
- Next, the Static Meshes UV’s where set up so that there would be as few UV Islands as possible. For this modular piece, the front and back faces of the box where mapped to the entirety of the 0 to 1 UV space. Then, the parts around the side where all welded together and scaled to match the current setup of the modular pieces.
- Finally, the Normals were modified to make sure that any smoothing artifacts on the vertical faces would be mitigated as much as possible.
When all of that was completed, the newly fixed-up modular piece was exported and then imported over the existing piece. This same process was then applied to the last LOD on every single Static Mesh in FNBR.
In the next section, we explain why all of this was done to show player-caused destruction.
They did ‘What’ with Geometry?
Now that all of the modular parts making up the building all have LOD’s that are in a state that uses as few triangles as possible, the Hierarchical Level of Detail tool (HLOD) was then used to generate a new version of the building, which looks like the following image.
This new version of the building, referred to as Medium HLOD or MHLOD, combines all of the very last LOD’s into one single Static Mesh and Texture. This significantly reduces the number of triangles that are needed to display the building, reducing the triangle count from 50,820 to just 2,880. This is a huge improvement, especially for lower-end devices like smartphones. This new version of the building will only be displayed on lower end devices and only when the player is about 30 meters from the building. This also helps to reduce the number of Materials that the building uses, which will further help reduce the number of resources that the buildings require to be rendered.
Going the Distance
Although the following information does not have to do with player-caused destruction, it is still good to know. While playing FNBR, you might have noticed that when viewing a building that is far off in the distance the destruction might not show up. This is because the very last LOD that you see is being generated using the Proxy Geometry tool. The Proxy Geometry tool is a new tool that was developed in-house as a replacement for Simplygon and is used to further reduce the triangle count of the MHLOD version of the building. While this version of the building does not show player-caused destruction, it is important because it helps reduce the rendering cost of the building when it is really far from the camera. When running the Proxy Geometry tool on the MHLOD version of the building used in this example, the building goes from 2,880 triangles to just 412 triangles. Now, the building is not going to look great using only 412 triangles as you can see from the image below.
Keep in mind that the 412 triangle version of the building will only be viewed at very far distances, so it will be very hard for the player to tell that it looks like the above image. To get a better idea of how this all comes together, check out the following GIF. In this GIF, we are seeing the building go from its highest triangle count version to the lowest triangle count version as a player would when playing.
Armed with a little bit more knowledge about how buildings are constructed and the tools that are used, including why those tools were used, we will now go over how this all comes together from an idea to a production-ready tool.
Technical Art to the Rescue
Now that we know a little bit more about how the buildings are constructed, we need to take a look at how to apply destruction to them so that it can be seen when the MHLOD meshes are in view. One of the key factors driving this is the need to show the player-caused destruction without changing anything about the MHLOD building. The reason for this is that changing or replacing pieces to show player-caused destruction would negate the benefits of having the MHLOD version of the buildings. Since this is a somewhat complicated issue to solve, we are going to need to call on a special kind of developer to help us out – we are going to need to bring in a Technical Artist.
For those of you who are not aware what the role of a Technical Artist entails, a Technical Artist (or TA) is an artist, coder, and designer all rolled into one person. From fixing complex Material issues to debugging a Blueprint, TA’s can fix many of the problems that arise during development. This is why TA’s are often tasked with developing solutions to some of the more complex problems as they generally know more about how all the systems and tools that are needed to create video games are interconnected and work with one another. For this particular task, we need a TA to come in to help break the problem down into its smallest components so that a simple yet robust solution can be created.
Breaking it Down
When trying to figure out a solution for a problem like this, the first thing that you want to do is break the problem down into its basic parts. This way you can get a better idea of all the parts that are involved and make small yet successful bits of progress. With this taken into consideration, the TA’s broke the problem of showing destruction on the MHLOD buildings into the following components:
- First, we need to add a new property called HLODDestructionIndex to the BuildingWall class that all the buildings use.
- Then, when building an HLOD, each Actor the building uses will be assigned an index which is not dependent on order.
- Next, each building foundation will need a Render Target big enough for 1 Texel per destroyable piece.
- Once that is completed, we would then need to modify how Mesh Merging is used with HLOD to add the ability to copy the Max LOD and apply custom vertex colors to the newly generated Static Mesh.
- Note that the Vertex Colors should be quantized such that using R, G and B gives 65k in values which should be more than we need.
- Now, whenever a piece of a building like a wall or a floor is destroyed, we read the HLODDestructionIndex value and then write the color black to the texel that is assigned to it. This will destroy the building piece as normal and the HLOD mesh sees no state changes but looks destroyed and the only work we did was to issue a Draw event containing 1 pixel per destruction event.
- Finally, in the Material, we take the ID that is packed into the Vertex Color and use that to look up into the destruction texture and then collapse the vertex to the origin (for example, scaling to zero) if the texel read is zero (a destroyed section).
Now that the TA’s have a plan of action, they can start to build a prototype inside of UE4 that will allow them to see if this idea will work or if they need to go back to the provable drawing board.
Luckily for the TA’s, the above approach worked like a charm, resulting in the MHLOD Static Mesh being destroyed without adding any additional rendering overhead like in the following GIF.
Now that the TA’s prototype works, it can be handed to a tools programmer to turn it into a real production tool.
Building it Back Up
Now that the prototype has been built, tested and reworked so many times that it is hard to distinguish the prototype from the original idea it will then be handed off to a tools programmer to be re-built using C++. The reason that we want to rebuild this in C++ is to ensure that things will run as fast as possible and also be as optimized as possible. Rebuilding this tool in C++ will also enable the needed properties to be grouped in the existing UI in a location that makes sense. Once that has all been completed, we can try this out in-game, like in the following video:
Tools You Can Use
In conclusion, we hope that this article helped you gain better insight into how the Technical Artists and engineers here at Epic addressed the problems that destruction caused with the introduction of Crossplay. Without their ingenious solution, the symphony of destruction that players can unleash in FNBR would not be possible.
Best of all, the tools mentioned in this blog post can be found within the 4.20 release of UE4 and we’re extremely excited to see how the Unreal Engine developer community puts them to use.
To read more about these tools, check out the links below:
Proxy Geometry Tool – The Proxy Geometry tool set was developed as a way to increase your Unreal Engine 4 projects performance while keeping the visual quality of your project uneffected.
Hierarchical Level of Detail – The Hierarchical Level of Detail tool or HLOD helps reduce the number of Actors that need to be rendered for the scene, increasing performance by lowering the number of draw calls per frame.